diff --git a/.travis.yml b/.travis.yml index 183d22e57..3dbe1e066 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,4 +45,4 @@ script: - mysql -uzmuser -pzmpass < db/zm_create.sql - mysql -uzmuser -pzmpass zm < db/test.monitor.sql - sudo zmpkg.pl start - - sudo zmfilter.pl -f purgewhenfull + - sudo zmfilter.pl --filter purgewhenfull diff --git a/distros/debian/postinst b/distros/debian/postinst index d06f9c641..39e3dfc32 100644 --- a/distros/debian/postinst +++ b/distros/debian/postinst @@ -3,51 +3,51 @@ set -e if [ "$1" = "configure" ]; then - if [ -e "/etc/init.d/mysql" ]; then - # - # Get mysql started if it isn't - # - if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then - invoke-rc.d mysql start - fi - if $(/etc/init.d/mysql status >/dev/null 2>&1); then - mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload - # test if database if already present... - if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then - cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf - echo 'grant lock tables, alter,select,insert,update,delete on zm.* to 'zmuser'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql - fi - invoke-rc.d zoneminder stop || true - zmupdate.pl --nointeractive + . /etc/zm/zm.conf - else - echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.' - fi - else - echo 'mysql not found, assuming remote server.' - fi - chown www-data:www-data /var/log/zm - chown www-data:www-data /var/lib/zm/ + # The logs can contain passwords, etc... so by setting group root, only www-data can read them, not people in the www-data group. + chown www-data:root /var/log/zm + chown www-data:www-data /var/lib/zm if [ -z "$2" ]; then - chown www-data:www-data -R /var/cache/zoneminder + chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/* fi -fi -# Ensure zoneminder is stopped... -if [ -x "/etc/init.d/zoneminder" ]; then - if invoke-rc.d zoneminder status ; then - invoke-rc.d zoneminder stop || exit $? + + # Do this every time the package is installed or upgraded + + if [ "$ZM_DB_HOST" = "localhost" ]; then + if [ -e "/etc/init.d/mysql" ]; then + # + # Get mysql started if it isn't + # + if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then + invoke-rc.d mysql start + fi + if $(/etc/init.d/mysql status >/dev/null 2>&1); then + mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload + # test if database if already present... + if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then + cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf + # This creates the user. + echo "grant lock tables, alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + else + echo "grant lock tables, alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + fi + + # Ensure zoneminder is stopped + invoke-rc.d zoneminder stop || true + zmupdate.pl --nointeractive + zmupdate.pl --nointeractive -f + invoke-rc.d zoneminder start || true + else + echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.' + fi + else + echo 'mysql not found, assuming remote server.' fi -fi - -if [ "$1" = "configure" ]; then - if [ -z "$2" ]; then - chown www-data:www-data /var/log/zm - chown www-data:www-data /var/lib/zm/ - chown www-data:www-data -R /var/cache/zoneminder else - chown www-data:www-data /var/log/zm - zmupdate.pl - fi + echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)" + fi + fi #DEBHELPER# diff --git a/distros/ubuntu1204/changelog b/distros/ubuntu1204/changelog index 74cf1d0b8..5cd712b13 100644 --- a/distros/ubuntu1204/changelog +++ b/distros/ubuntu1204/changelog @@ -1,3 +1,9 @@ +zoneminder (1.30.2-trusty-2016042801) trusty; urgency=medium + + * Merge video + + -- Isaac Connor Thu, 28 Apr 2016 12:54:08 -0400 + zoneminder (1.28.1+1-vivid-SNAPSHOT2015081701) vivid; urgency=medium * include api, switch to cmake build diff --git a/distros/ubuntu1204/zoneminder.postinst b/distros/ubuntu1204/zoneminder.postinst index e7810e468..7c01cdde4 100644 --- a/distros/ubuntu1204/zoneminder.postinst +++ b/distros/ubuntu1204/zoneminder.postinst @@ -3,11 +3,51 @@ set -e if [ "$1" = "configure" ]; then - chown www-data:root /var/log/zm - chown www-data:www-data /var/lib/zm - if [ -z "$2" ]; then - chown www-data:www-data -R /var/cache/zoneminder - fi + + . /etc/zm/zm.conf + + # The logs can contain passwords, etc... so by setting group root, only www-data can read them, not people in the www-data group + chown www-data:root /var/log/zm + chown www-data:www-data /var/lib/zm + if [ -z "$2" ]; then + chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/* + fi + + # Do this every time the package is installed or upgraded + + if [ "$ZM_DB_HOST" = "localhost" ]; then + if [ -e "/etc/init.d/mysql" ]; then + # + # Get mysql started if it isn't + # + if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then + invoke-rc.d mysql start + fi + if $(/etc/init.d/mysql status >/dev/null 2>&1); then + mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload + # test if database if already present... + if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then + cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf + # This creates the user. + echo "grant lock tables, alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + else + echo "grant lock tables, alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + fi + + # Ensure zoneminder is stopped + invoke-rc.d zoneminder stop || true + zmupdate.pl --nointeractive + zmupdate.pl --nointeractive -f + invoke-rc.d zoneminder start || true + else + echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.' + fi + else + echo 'mysql not found, assuming remote server.' + fi + else + echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)" + fi fi #DEBHELPER# diff --git a/distros/ubuntu1410/changelog b/distros/ubuntu1410/changelog index 74129432f..55e3d17b0 100644 --- a/distros/ubuntu1410/changelog +++ b/distros/ubuntu1410/changelog @@ -1,3 +1,15 @@ +zoneminder (1.30.2-trusty-2016033001) trusty; urgency=medium + + * merge master + + -- Isaac Connor Wed, 30 Mar 2016 14:09:48 -0400 + +zoneminder (1.30.2-trusty-2016032901) trusty; urgency=medium + + * filter fixes, merge options rework by Kyle + + -- Isaac Connor Tue, 29 Mar 2016 12:27:57 -0400 + zoneminder (1.30.2-trusty-2016030702) trusty; urgency=medium * diff --git a/distros/ubuntu1504/control b/distros/ubuntu1504/control index 50dee74c6..0b32a37ac 100644 --- a/distros/ubuntu1504/control +++ b/distros/ubuntu1504/control @@ -6,6 +6,7 @@ Uploaders: Vagrant Cascadian Build-Depends: debhelper (>= 9), dh-systemd, python-sphinx | python3-sphinx, apache2-dev, dh-linktree ,cmake ,libavcodec-ffmpeg-dev, libavformat-ffmpeg-dev, libswscale-ffmpeg-dev, libavutil-ffmpeg-dev, libavdevice-ffmpeg-dev + ,libx264-dev, libmp4v2-dev, ,libbz2-dev ,libgcrypt-dev ,libcurl4-gnutls-dev @@ -34,10 +35,8 @@ Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends} ,javascript-common ,libav-tools - ,libdate-manip-perl + ,libdate-manip-perl, libmime-lite-perl, libmime-tools-perl ,libdbd-mysql-perl - ,libmime-lite-perl - ,libmime-tools-perl ,libphp-serialization-perl ,libmodule-load-conditional-perl ,libnet-sftp-foreign-perl @@ -57,12 +56,12 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends} ,libsys-cpu-perl, libsys-meminfo-perl ,mysql-client | virtual-mysql-client ,perl-modules - ,php5-mysql + ,php5-mysql | php-mysql, php5-gd | php-gd ,policykit-1 ,rsyslog | system-log-daemon ,zip Recommends: ${misc:Recommends} - ,libapache2-mod-php5 | php5-fpm + ,libapache2-mod-php5 | libapache2-mod-php7 | php5-fpm ,mysql-server | virtual-mysql-server ,zoneminder-doc (>= ${source:Version}) Suggests: fcgiwrap, logrotate diff --git a/distros/ubuntu1504/zoneminder.postinst b/distros/ubuntu1504/zoneminder.postinst index 82b256e6b..64699d1ca 100644 --- a/distros/ubuntu1504/zoneminder.postinst +++ b/distros/ubuntu1504/zoneminder.postinst @@ -2,28 +2,57 @@ set -e -. /etc/zm/zm.conf - if [ "$1" = "configure" ]; then - chown www-data:root /var/log/zm - chown www-data:www-data /var/lib/zm - if [ -z "$2" ]; then - chown www-data:www-data -R /var/cache/zoneminder - fi + + . /etc/zm/zm.conf + + # The logs can contain passwords, etc... so by setting group root, only www-data can read them, not people in the www-data group + chown www-data:root /var/log/zm + chown www-data:www-data /var/lib/zm + if [ -z "$2" ]; then + chown www-data:www-data /var/cache/zoneminder /var/cache/zoneminder/* + fi # Do this every time the package is installed or upgraded - # Test for database presence to avoid failure of zmupdate.pl - - # Ensure zoneminder is stopped - deb-systemd-invoke stop zoneminder.service || exit $? if [ "$ZM_DB_HOST" = "localhost" ]; then - echo 'grant lock tables, create, index, alter on zm.* to 'zmuser'@localhost identified by "zmpass";' | mysql --defaults-file=/etc/mysql/debian.cnf mysql - # Run the ZoneMinder update tool - zmupdate.pl --nointeractive - else + + if [ -e "/etc/init.d/mysql" ]; then + + # + # Get mysql started if it isn't + # + if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then + deb-systemd-invoke start mysql.service || exit $? + fi + + if $(/etc/init.d/mysql status >/dev/null 2>&1); then + mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload + # test if database if already present... + if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then + cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf + # This creates the user. + echo "grant lock tables,alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost identified by \"${ZM_DB_PASS}\";" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + else + echo "grant lock tables,alter,select,insert,update,delete,create,index on ${ZM_DB_NAME}.* to '${ZM_DB_USER}'@localhost;" | mysql --defaults-file=/etc/mysql/debian.cnf mysql + fi + + # Ensure zoneminder is stopped + deb-systemd-invoke stop zoneminder.service || exit $? + zmupdate.pl --nointeractive + zmupdate.pl --nointeractive -f + deb-systemd-invoke start zoneminder.service || exit $? + + else + echo 'NOTE: mysql not running, please start mysql and run dpkg-reconfigure zoneminder when it is running.' + fi + else + echo 'mysql not found, assuming remote server.' + fi + + else echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)" - fi; + fi fi diff --git a/docs/faq.rst b/docs/faq.rst index 5aa736ee8..1c5c36d09 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -514,6 +514,8 @@ You do not need to rebuild ZM for X10 support. You will need to install the perl Extending Zoneminder ------------------------ +.. _runstate_cron_example: + How can I get ZM to do different things at different times of day or week? ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/userguide/gettingstarted.rst b/docs/userguide/gettingstarted.rst index 73f6e2783..b2e92f63f 100644 --- a/docs/userguide/gettingstarted.rst +++ b/docs/userguide/gettingstarted.rst @@ -67,8 +67,14 @@ own empty screen. * **D**: This is the core of ZoneMinder - recording events. It gives you a count of how many events were recorded over the hour, day, week, month. * **E**: These are the "Zones". Zones are areas within the camera that you mark as 'hotspots' for motion detection. Simply put, when you first configure your monitors (cameras), by default Zoneminder uses the entire field of view of the camera to detect motion. You may not want this. You may want to create "zones" specifically for detecting motion and ignore others. For example, lets consider a room with a fan that spins. You surely don't want to consider the fan moving continuously a reason for triggering a record? Probably not - in that case, you'd leave the fan out while making your zones. * **F**: This is the "source" column that tells you the type of the camera - if its an IP camera, a USB camera or more. In this example, they are all IP cameras. Note the color red on item F ? Well that means there is something wrong with that camera. No wonder the log also shows red. Good indication for you to tap on logs and investigate -* **G**: This defines how Zoneminder will record events. There are various modes. In brief Modect == record if a motion is detected,Record = always record 24x7, Mocord = always record PLUS detect motion, Monitor = just provide a live view but don't record anytime, Nodect = Don't record till an externa entity via zmtrigger tells Zoneminder to (this is advanced usage). +* **G**: This defines how Zoneminder will record events. There are various modes. In brief Modect == record if a motion is detected,Record = always record 24x7, Mocord = always record PLUS detect motion, Monitor = just provide a live view but don't record anytime, Nodect = Don't record till an external entity via zmtrigger tells Zoneminder to (this is advanced usage). * **H**: If you click on these links you can view a "Montage" of all your configured monitors or cycle through each one +* **I**: One of the most often missed features is the ability of ZoneMinder to maintain "run states". If you click on the "Running" text, ZoneMinder brings up a popup that allows you to define additional "states" (referred to as runstates). A runstate is essentially a snapshot that records the state of each monitor and you can switch between states easily. For example, you might have a run state defined that switches all monitors to "monitor" mode in which they are not recording anything while another state that sets some of the monitors to "modect". Why would you want this? A great example is to disable recording when you are at home and enable when you are away, based on time of day or other triggers. You can switch states by selecting an appropriate state manually, or do it automatically via cron jobs, for example. An example of using cron to automatically switch is provided in the :ref:`FAQ `. More esoteric examples of switching run states based on phone location can be found `here `__. + +Here is an example of multiple run states that I've defined. Each one of these runstates changes the mode of specific monitors depending on time of day and other conditions. Use your imagination to decide which conditions require state changes. + +.. image:: images/runstates.png + Adding Monitors diff --git a/docs/userguide/images/getting-started-understand-console.png b/docs/userguide/images/getting-started-understand-console.png index 805917f23..f332b4977 100644 Binary files a/docs/userguide/images/getting-started-understand-console.png and b/docs/userguide/images/getting-started-understand-console.png differ diff --git a/docs/userguide/images/runstates.png b/docs/userguide/images/runstates.png new file mode 100644 index 000000000..ced74cb55 Binary files /dev/null and b/docs/userguide/images/runstates.png differ diff --git a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in index 18306e52f..fc4143d8a 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in +++ b/scripts/ZoneMinder/lib/ZoneMinder/ConfigData.pm.in @@ -3825,6 +3825,41 @@ body = "ZM alarm detected - %EL% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% s readonly => 1, category => "dynamic", }, + { + name => "ZM_SSMTP_MAIL", + default => "no", + description => qqq(" + Use a SSMTP mail server if available. + NEW_MAIL_MODULES must be enabled + "), + requires => [ + { name => "ZM_OPT_EMAIL", value => "yes" }, + { name => "ZM_OPT_MESSAGE", value => "yes" }, + { name => "ZM_NEW_MAIL_MODULES", value => "yes" } + ], + help => qqq(" + SSMTP is a lightweight and efficient method to send email. + The SSMTP application is not installed by default. + NEW_MAIL_MODULES must also be enabled. + Please visit: http://www.zoneminder.com/wiki/index.php/How_to_get_ssmtp_working_with_Zoneminder + for setup and configuration help. + "), + type => $types{boolean}, + category => "mail", + }, + { + name => "ZM_SSMTP_PATH", + default => "", + description => "SSMTP executable path", + requires => [{ name => "ZM_SSMTP_MAIL", value => "yes" }], + help => qqq(" + Recommend setting the path to the SSMTP application. + If path is not defined. Zoneminder will try to determine + the path via shell command. Example path: /usr/sbin/ssmtp. + "), + type => $types{string}, + category => "mail", + }, ); our %options_hash = map { ( $_->{name}, $_ ) } @options; diff --git a/scripts/zmaudit.pl.in b/scripts/zmaudit.pl.in index c95f65441..a8cebde89 100644 --- a/scripts/zmaudit.pl.in +++ b/scripts/zmaudit.pl.in @@ -155,10 +155,12 @@ MAIN: while( $loop ) { Fatal("ZM_AUDIT_MIN_AGE is not set in config."); } + my %Monitors; my $db_monitors; - my $monitorSelectSql = "select Id from Monitors order by Id"; + my $monitorSelectSql = "select * from Monitors order by Id"; my $monitorSelectSth = $dbh->prepare_cached( $monitorSelectSql ) or Fatal( "Can't prepare '$monitorSelectSql': ".$dbh->errstr() ); + my $eventSelectSql = "SELECT Id, (unix_timestamp() - unix_timestamp(StartTime)) as Age FROM Events WHERE MonitorId = ? ORDER BY Id"; my $eventSelectSth = $dbh->prepare_cached( $eventSelectSql ) @@ -169,6 +171,8 @@ MAIN: while( $loop ) { or Fatal( "Can't execute: ".$monitorSelectSth->errstr() ); while( my $monitor = $monitorSelectSth->fetchrow_hashref() ) { + $Monitors{$$monitor{Id}} = $monitor; + Debug( "Found database monitor '$monitor->{Id}'" ); my $db_events = $db_monitors->{$monitor->{Id}} = {}; my $res = $eventSelectSth->execute( $monitor->{Id} ) @@ -467,20 +471,30 @@ MAIN: while( $loop ) { # New audit to close any events that were left open for longer than MIN_AGE seconds my $selectUnclosedEventsSql = - "SELECT E.Id, - max(F.TimeStamp) as EndTime, - unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartTime) as Length, - max(F.FrameId) as Frames, + #"SELECT E.Id, ANY_VALUE(E.MonitorId), +# + #max(F.TimeStamp) as EndTime, + #unix_timestamp(max(F.TimeStamp)) - unix_timestamp(E.StartTime) as Length, + #max(F.FrameId) as Frames, + #count(if(F.Score>0,1,NULL)) as AlarmFrames, + #sum(F.Score) as TotScore, + #max(F.Score) as MaxScore + #FROM Events as E + #INNER JOIN Frames as F on E.Id = F.EventId + #WHERE isnull(E.Frames) or isnull(E.EndTime) + #GROUP BY E.Id HAVING EndTime < (now() - interval ".$Config{ZM_AUDIT_MIN_AGE}." second)" + #; + "SELECT *, unix_timestamp(StartTime) AS TimeStamp FROM Events WHERE EndTime IS NULL AND StartTime < (now() - interval ".$Config{ZM_AUDIT_MIN_AGE}." second)"; + + my $selectFrameDataSql = "SELECT max(TimeStamp) as EndTime, unix_timestamp(max(TimeStamp)) AS EndTimeStamp, max(FrameId) as Frames, count(if(F.Score>0,1,NULL)) as AlarmFrames, sum(F.Score) as TotScore, - max(F.Score) as MaxScore, - M.EventPrefix as Prefix - FROM Events as E - LEFT JOIN Monitors as M on E.MonitorId = M.Id - INNER JOIN Frames as F on E.Id = F.EventId - WHERE isnull(E.Frames) or isnull(E.EndTime) - GROUP BY E.Id HAVING EndTime < (now() - interval ".$Config{ZM_AUDIT_MIN_AGE}." second)" - ; + max(F.Score) as MaxScore + FROM Frames WHERE EventId=?"; + my $selectFrameDataSth = $dbh->prepare_cached($selectFrameDataSql) + or Fatal( "Can't prepare '$selectFrameDataSql': ".$dbh->errstr() ); + + my $selectUnclosedEventsSth = $dbh->prepare_cached( $selectUnclosedEventsSql ) or Fatal( "Can't prepare '$selectUnclosedEventsSql': ".$dbh->errstr() ); my $updateUnclosedEventsSql = @@ -505,26 +519,32 @@ MAIN: while( $loop ) { aud_print( "Found open event '$event->{Id}'" ); if ( confirm( 'close', 'closing' ) ) { - $res = $updateUnclosedEventsSth->execute - ( - sprintf("%s%d%s", - $event->{Prefix}, - $event->{Id}, - RECOVER_TAG - ), - $event->{EndTime}, - $event->{Length}, - $event->{Frames}, - $event->{AlarmFrames}, - $event->{TotScore}, - $event->{AlarmFrames} - ? int($event->{TotScore} / $event->{AlarmFrames}) - : 0 - , - $event->{MaxScore}, - RECOVER_TEXT, - $event->{Id} - ) or Fatal( "Can't execute: ".$updateUnclosedEventsSth->errstr() ); + $res = $selectFrameDataSth->execute( $event->{Id} ); + my $frame = $selectFrameDataSth->fetchrow_hashref(); + if ( $frame ) { + $res = $updateUnclosedEventsSth->execute + ( + sprintf("%s%d%s", + $Monitors{$event->{MonitorId}}->{EventPrefix}, + $event->{Id}, + RECOVER_TAG + ), + $frame->{EndTime}, + $frame->{EndTimeStamp} - $event->{TimeStamp}, + $frame->{Frames}, + $frame->{AlarmFrames}, + $frame->{TotScore}, + $frame->{AlarmFrames} + ? int($frame->{TotScore} / $frame->{AlarmFrames}) + : 0 + , + $frame->{MaxScore}, + RECOVER_TEXT, + $event->{Id} + ) or Fatal( "Can't execute: ".$updateUnclosedEventsSth->errstr() ); + } else { + Error("SHOULD DELETE"); + } # end if has frame data } } diff --git a/scripts/zmdc.pl.in b/scripts/zmdc.pl.in index b068b9a49..36d5e922a 100644 --- a/scripts/zmdc.pl.in +++ b/scripts/zmdc.pl.in @@ -862,7 +862,7 @@ sub killAll my $killall; if ( '@HOST_OS@' eq 'BSD' ) { - $killall = 'killall -'; + $killall = 'killall -q -'; } elsif ( '@HOST_OS@' eq 'solaris' ) { $killall = 'pkill -'; } else { diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 511754a33..7c8244f83 100755 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -779,9 +779,31 @@ sub sendEmail Disposition => "attachment" ); } + if ( $Config{ZM_SSMTP_MAIL} ){ + + my $ssmtp_location = $Config{ZM_SSMTP_PATH}; + + if( ! $ssmtp_location ){ + + $ssmtp_location = qx('which ssmtp'); + + if ( logDebugging() ) + { + Debug( "which ssmtp: $ssmtp_location - set ssmtp path in options to suppress this message\n" ); + } + + } + + $mail->send( 'sendmail', $ssmtp_location, $Config{ZM_EMAIL_ADDRESS} ); + + }else{ + + MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 ); + $mail->send(); + } ### Send the Message - MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 ); - $mail->send(); + #MIME::Lite->send( "smtp", $Config{ZM_EMAIL_HOST}, Timeout=>60 ); + #$mail->send(); } else { diff --git a/src/zm.h b/src/zm.h index a60ab655d..0c780b244 100644 --- a/src/zm.h +++ b/src/zm.h @@ -26,8 +26,8 @@ #include "zm_config.h" #ifdef SOLARIS -#undef DEFAULT_TYPE // pthread defines this which breaks StreamType DEFAULT_TYPE -#include // define strerror() and friends +#undef DEFAULT_TYPE // pthread defines this which breaks StreamType DEFAULT_TYPE +#include // define strerror() and friends #endif #include "zm_logger.h" diff --git a/src/zm_bigfont.h b/src/zm_bigfont.h index b653a7f4f..96ba479dd 100644 --- a/src/zm_bigfont.h +++ b/src/zm_bigfont.h @@ -1,6155 +1,6155 @@ /***********************************************************/ -/* */ -/* Font file generated by schrorg */ -/* based on the font file generated by rthelen */ -/* using utils/mk_bigfont.pl */ -/* */ +/* */ +/* Font file generated by schrorg */ +/* based on the font file generated by rthelen */ +/* using utils/mk_bigfont.pl */ +/* */ /***********************************************************/ static unsigned int bigfontdata[] = { - /* 0 0x00 '^A' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 1 0x01 '^B' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 2 0x02 '^C' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 3 0x03 '^D' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 4 0x04 '^E' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 5 0x05 '^F' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 6 0x06 '^G' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 7 0x07 '^H' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 8 0x08 '^I' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 9 0x09 '^J' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 10 0x0a '^K' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 11 0x0b '^L' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 12 0x0c '^M' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 13 0x0d '^N' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 14 0x0e '^O' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 15 0x0f '^P' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 16 0x10 '^Q' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 17 0x11 '^R' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 18 0x12 '^S' */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 19 0x13 '^T' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 20 0x14 '^U' */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 21 0x15 '^V' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 22 0x16 '^W' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 23 0x17 '^X' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 24 0x18 '^Y' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 25 0x19 '^Z' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 26 0x1a '^[' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 27 0x1b '^\' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 28 0x1c '^]' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 29 0x1d '^^' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 30 0x1e '^_' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 31 0x1f '^`' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 32 0x20 ' ' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 33 0x21 '!' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 34 0x22 '"' */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 35 0x23 '#' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 36 0x24 '$' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 37 0x25 '%' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 38 0x26 '&' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 39 0x27 ''' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 40 0x28 '(' */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 41 0x29 ')' */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 42 0x2a '*' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 43 0x2b '+' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 44 0x2c ',' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 45 0x2d '-' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 46 0x2e '.' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 47 0x2f '/' */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 48 0x30 '0' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 49 0x31 '1' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x3f0, /* 000000 0000 */ - 0x3f0, /* 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 50 0x32 '2' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 51 0x33 '3' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 52 0x34 '4' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x3f0, /* 000000 0000 */ - 0x3f0, /* 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 53 0x35 '5' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 54 0x36 '6' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 55 0x37 '7' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 56 0x38 '8' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 57 0x39 '9' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 58 0x3a ':' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 59 0x3b ';' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 60 0x3c '<' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 61 0x3d '=' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 62 0x3e '>' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 63 0x3f '?' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 64 0x40 '@' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3f30, /* 00 00 0000 */ - 0x3f30, /* 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 65 0x41 'A' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 66 0x42 'B' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 67 0x43 'C' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 68 0x44 'D' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 69 0x45 'E' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 70 0x46 'F' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 71 0x47 'G' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 72 0x48 'H' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 73 0x49 'I' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 74 0x4a 'J' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 75 0x4b 'K' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3c00, /* 00 0000000000 */ - 0x3c00, /* 00 0000000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 76 0x4c 'L' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 77 0x4d 'M' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3cf0, /* 00 00 0000 */ - 0x3cf0, /* 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 78 0x4e 'N' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 79 0x4f 'O' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 80 0x50 'P' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 81 0x51 'Q' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 82 0x52 'R' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 83 0x53 'S' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 84 0x54 'T' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 85 0x55 'U' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 86 0x56 'V' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 87 0x57 'W' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3cf0, /* 00 00 0000 */ - 0x3cf0, /* 00 00 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 88 0x58 'X' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 89 0x59 'Y' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 90 0x5a 'Z' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 91 0x5b '[' */ - 0xf0, /* 00000000 0000 */ - 0xf0, /* 00000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xf0, /* 00000000 0000 */ - 0xf0, /* 00000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 92 0x5c '\' */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc, /* 000000000000 00 */ - 0xc, /* 000000000000 00 */ - 0xc, /* 000000000000 00 */ - 0xc, /* 000000000000 00 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 93 0x5d ']' */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 94 0x5e '^' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 95 0x5f '_' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ffc, /* 00 00 */ - 0x3ffc, /* 00 00 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 96 0x60 '`' */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 97 0x61 'a' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 98 0x62 'b' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 99 0x63 'c' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 100 0x64 'd' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 101 0x65 'e' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 102 0x66 'f' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf0, /* 00000000 0000 */ - 0xf0, /* 00000000 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 103 0x67 'g' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 104 0x68 'h' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 105 0x69 'i' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 106 0x6a 'j' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3c00, /* 00 0000000000 */ - 0x3c00, /* 00 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 107 0x6b 'k' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3f00, /* 00 00000000 */ - 0x3f00, /* 00 00000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 108 0x6c 'l' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 109 0x6d 'm' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 110 0x6e 'n' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 111 0x6f 'o' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 112 0x70 'p' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 113 0x71 'q' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 114 0x72 'r' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 115 0x73 's' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 116 0x74 't' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xf0, /* 00000000 0000 */ - 0xf0, /* 00000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 117 0x75 'u' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 118 0x76 'v' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 119 0x77 'w' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 120 0x78 'x' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 121 0x79 'y' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 122 0x7a 'z' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 123 0x7b '{' */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 124 0x7c '|' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 125 0x7d '}' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 126 0x7e '~' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 127 0x7f '^?' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 128 0x80 '\200' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 129 0x81 '\201' */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 130 0x82 '\202' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 131 0x83 '\203' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 132 0x84 '\204' */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 133 0x85 '\205' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 134 0x86 '\206' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 135 0x87 '\207' */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 136 0x88 '\210' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 137 0x89 '\211' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 138 0x8a '\212' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 139 0x8b '\213' */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 140 0x8c '\214' */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 141 0x8d '\215' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 142 0x8e '\216' */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 143 0x8f '\217' */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 144 0x90 '\220' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 145 0x91 '\221' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 146 0x92 '\222' */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 147 0x93 '\223' */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 148 0x94 '\224' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 149 0x95 '\225' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 150 0x96 '\226' */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 151 0x97 '\227' */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 152 0x98 '\230' */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 153 0x99 '\231' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 154 0x9a '\232' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 155 0x9b '\233' */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 156 0x9c '\234' */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 157 0x9d '\235' */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 158 0x9e '\236' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 159 0x9f '\237' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 160 0xa0 '\240' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 161 0xa1 '\241' */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 162 0xa2 '\242' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 163 0xa3 '\243' */ - 0xf00, /* 0000 00000000 */ - 0xf00, /* 0000 00000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3f00, /* 00 00000000 */ - 0x3f00, /* 00 00000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 164 0xa4 '\244' */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 165 0xa5 '\245' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 166 0xa6 '\246' */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 167 0xa7 '\247' */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 168 0xa8 '\250' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3f00, /* 00 00000000 */ - 0x3f00, /* 00 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 169 0xa9 '\251' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3f00, /* 00 00000000 */ - 0x3f00, /* 00 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xf30, /* 0000 00 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x3f00, /* 00 00000000 */ - 0x3f00, /* 00 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 170 0xaa '\252' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3fcc, /* 00 00 00 */ - 0x3fcc, /* 00 00 00 */ - 0xcfc, /* 0000 00 00 */ - 0xcfc, /* 0000 00 00 */ - 0xcfc, /* 0000 00 00 */ - 0xcfc, /* 0000 00 00 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 171 0xab '\253' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 172 0xac '\254' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 173 0xad '\255' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 174 0xae '\256' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3fc0, /* 00 000000 */ - 0x3fc0, /* 00 000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x33f0, /* 00 00 0000 */ - 0x33f0, /* 00 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 175 0xaf '\257' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 176 0xb0 '\260' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3cf0, /* 00 00 0000 */ - 0x3cf0, /* 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3cf0, /* 00 00 0000 */ - 0x3cf0, /* 00 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 177 0xb1 '\261' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 178 0xb2 '\262' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 179 0xb3 '\263' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3f0, /* 000000 0000 */ - 0x3f0, /* 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 180 0xb4 '\264' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 181 0xb5 '\265' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x3f30, /* 00 00 0000 */ - 0x3f30, /* 00 00 0000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 182 0xb6 '\266' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xf0, /* 00000000 0000 */ - 0xf0, /* 00000000 0000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 183 0xb7 '\267' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 184 0xb8 '\270' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 185 0xb9 '\271' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 186 0xba '\272' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3c00, /* 00 0000000000 */ - 0x3c00, /* 00 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 187 0xbb '\273' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3f0, /* 000000 0000 */ - 0x3f0, /* 000000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x3f0, /* 000000 0000 */ - 0x3f0, /* 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 188 0xbc '\274' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 189 0xbd '\275' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3cf0, /* 00 00 0000 */ - 0x3cf0, /* 00 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 190 0xbe '\276' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x33f0, /* 00 00 0000 */ - 0x33f0, /* 00 00 0000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 191 0xbf '\277' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x30f0, /* 00 0000 0000 */ - 0x30f0, /* 00 0000 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0x3c30, /* 00 0000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 192 0xc0 '\300' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 193 0xc1 '\301' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 194 0xc2 '\302' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 195 0xc3 '\303' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xf0, /* 00000000 0000 */ - 0xf0, /* 00000000 0000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0xc00, /* 0000 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 196 0xc4 '\304' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3c00, /* 00 0000000000 */ - 0x3c00, /* 00 0000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 197 0xc5 '\305' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3000, /* 00 000000000000 */ - 0x3000, /* 00 000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 198 0xc6 '\306' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 199 0xc7 '\307' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 200 0xc8 '\310' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0xc30, /* 0000 0000 0000 */ - 0x30c0, /* 00 0000 000000 */ - 0x30c0, /* 00 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 201 0xc9 '\311' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 202 0xca '\312' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 203 0xcb '\313' */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 204 0xcc '\314' */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 205 0xcd '\315' */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 206 0xce '\316' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x33c0, /* 00 00 000000 */ - 0x33c0, /* 00 00 000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 207 0xcf '\317' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3330, /* 00 00 00 0000 */ - 0x3330, /* 00 00 00 0000 */ - 0x33f0, /* 00 00 0000 */ - 0x33f0, /* 00 00 0000 */ - 0x3300, /* 00 00 00000000 */ - 0x3300, /* 00 00 00000000 */ - 0xcf0, /* 0000 00 0000 */ - 0xcf0, /* 0000 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 208 0xd0 '\320' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 209 0xd1 '\321' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ffc, /* 00 00 */ - 0x3ffc, /* 00 00 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 210 0xd2 '\322' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 211 0xd3 '\323' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0x330, /* 000000 00 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 212 0xd4 '\324' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 213 0xd5 '\325' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3c0, /* 000000 000000 */ - 0x3c0, /* 000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0xc0, /* 00000000 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 214 0xd6 '\326' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ff0, /* 00 0000 */ - 0x3ff0, /* 00 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 215 0xd7 '\327' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x300, /* 000000 00000000 */ - 0x300, /* 000000 00000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 216 0xd8 '\330' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xcc0, /* 0000 00 000000 */ - 0xcc0, /* 0000 00 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0x3030, /* 00 000000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x30, /* 0000000000 0000 */ - 0x30, /* 0000000000 0000 */ - 0xfc0, /* 0000 000000 */ - 0xfc0, /* 0000 000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 217 0xd9 '\331' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ffc, /* 00 00 */ - 0x3ffc, /* 00 00 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ffc, /* 00 00 */ - 0x3ffc, /* 00 00 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x3ffc, /* 00 00 */ - 0x3ffc, /* 00 00 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 218 0xda '\332' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 219 0xdb '\333' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 220 0xdc '\334' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 221 0xdd '\335' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 222 0xde '\336' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 223 0xdf '\337' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 224 0xe0 '\340' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 225 0xe1 '\341' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 226 0xe2 '\342' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 227 0xe3 '\343' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 228 0xe4 '\344' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 229 0xe5 '\345' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 230 0xe6 '\346' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 231 0xe7 '\347' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 232 0xe8 '\350' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 233 0xe9 '\351' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 234 0xea '\352' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 235 0xeb '\353' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 236 0xec '\354' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 237 0xed '\355' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 238 0xee '\356' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 239 0xef '\357' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 240 0xf0 '\360' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 241 0xf1 '\361' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 242 0xf2 '\362' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 243 0xf3 '\363' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 244 0xf4 '\364' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 245 0xf5 '\365' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 246 0xf6 '\366' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 247 0xf7 '\367' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 248 0xf8 '\370' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 249 0xf9 '\371' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 250 0xfa '\372' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 251 0xfb '\373' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 252 0xfc '\374' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 253 0xfd '\375' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 254 0xfe '\376' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - - /* 255 0xff '\377' */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0xff0, /* 0000 0000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ - 0x0, /* 0000000000000000 */ + /* 0 0x00 '^A' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 1 0x01 '^B' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 2 0x02 '^C' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 3 0x03 '^D' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 4 0x04 '^E' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 5 0x05 '^F' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 6 0x06 '^G' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 7 0x07 '^H' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 8 0x08 '^I' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 9 0x09 '^J' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 10 0x0a '^K' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 11 0x0b '^L' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 12 0x0c '^M' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 13 0x0d '^N' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 14 0x0e '^O' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 15 0x0f '^P' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 16 0x10 '^Q' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 17 0x11 '^R' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 18 0x12 '^S' */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 19 0x13 '^T' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 20 0x14 '^U' */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 21 0x15 '^V' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 22 0x16 '^W' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 23 0x17 '^X' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 24 0x18 '^Y' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 25 0x19 '^Z' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 26 0x1a '^[' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 27 0x1b '^\' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 28 0x1c '^]' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 29 0x1d '^^' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 30 0x1e '^_' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 31 0x1f '^`' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 32 0x20 ' ' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 33 0x21 '!' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 34 0x22 '"' */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 35 0x23 '#' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 36 0x24 '$' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 37 0x25 '%' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 38 0x26 '&' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 39 0x27 ''' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 40 0x28 '(' */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 41 0x29 ')' */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 42 0x2a '*' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 43 0x2b '+' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 44 0x2c ',' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 45 0x2d '-' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 46 0x2e '.' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 47 0x2f '/' */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 48 0x30 '0' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 49 0x31 '1' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x3f0, /* 000000 0000 */ + 0x3f0, /* 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 50 0x32 '2' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 51 0x33 '3' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 52 0x34 '4' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x3f0, /* 000000 0000 */ + 0x3f0, /* 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 53 0x35 '5' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 54 0x36 '6' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 55 0x37 '7' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 56 0x38 '8' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 57 0x39 '9' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 58 0x3a ':' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 59 0x3b ';' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 60 0x3c '<' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 61 0x3d '=' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 62 0x3e '>' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 63 0x3f '?' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 64 0x40 '@' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3f30, /* 00 00 0000 */ + 0x3f30, /* 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 65 0x41 'A' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 66 0x42 'B' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 67 0x43 'C' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 68 0x44 'D' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 69 0x45 'E' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 70 0x46 'F' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 71 0x47 'G' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 72 0x48 'H' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 73 0x49 'I' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 74 0x4a 'J' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 75 0x4b 'K' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3c00, /* 00 0000000000 */ + 0x3c00, /* 00 0000000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 76 0x4c 'L' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 77 0x4d 'M' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3cf0, /* 00 00 0000 */ + 0x3cf0, /* 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 78 0x4e 'N' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 79 0x4f 'O' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 80 0x50 'P' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 81 0x51 'Q' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 82 0x52 'R' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 83 0x53 'S' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 84 0x54 'T' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 85 0x55 'U' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 86 0x56 'V' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 87 0x57 'W' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3cf0, /* 00 00 0000 */ + 0x3cf0, /* 00 00 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 88 0x58 'X' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 89 0x59 'Y' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 90 0x5a 'Z' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 91 0x5b '[' */ + 0xf0, /* 00000000 0000 */ + 0xf0, /* 00000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xf0, /* 00000000 0000 */ + 0xf0, /* 00000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 92 0x5c '\' */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc, /* 000000000000 00 */ + 0xc, /* 000000000000 00 */ + 0xc, /* 000000000000 00 */ + 0xc, /* 000000000000 00 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 93 0x5d ']' */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 94 0x5e '^' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 95 0x5f '_' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ffc, /* 00 00 */ + 0x3ffc, /* 00 00 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 96 0x60 '`' */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 97 0x61 'a' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 98 0x62 'b' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 99 0x63 'c' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 100 0x64 'd' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 101 0x65 'e' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 102 0x66 'f' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf0, /* 00000000 0000 */ + 0xf0, /* 00000000 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 103 0x67 'g' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 104 0x68 'h' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 105 0x69 'i' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 106 0x6a 'j' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3c00, /* 00 0000000000 */ + 0x3c00, /* 00 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 107 0x6b 'k' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3f00, /* 00 00000000 */ + 0x3f00, /* 00 00000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 108 0x6c 'l' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 109 0x6d 'm' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 110 0x6e 'n' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 111 0x6f 'o' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 112 0x70 'p' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 113 0x71 'q' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 114 0x72 'r' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 115 0x73 's' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 116 0x74 't' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xf0, /* 00000000 0000 */ + 0xf0, /* 00000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 117 0x75 'u' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 118 0x76 'v' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 119 0x77 'w' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 120 0x78 'x' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 121 0x79 'y' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 122 0x7a 'z' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 123 0x7b '{' */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 124 0x7c '|' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 125 0x7d '}' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 126 0x7e '~' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 127 0x7f '^?' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 128 0x80 '\200' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 129 0x81 '\201' */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 130 0x82 '\202' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 131 0x83 '\203' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 132 0x84 '\204' */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 133 0x85 '\205' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 134 0x86 '\206' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 135 0x87 '\207' */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 136 0x88 '\210' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 137 0x89 '\211' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 138 0x8a '\212' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 139 0x8b '\213' */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 140 0x8c '\214' */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 141 0x8d '\215' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 142 0x8e '\216' */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 143 0x8f '\217' */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 144 0x90 '\220' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 145 0x91 '\221' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 146 0x92 '\222' */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 147 0x93 '\223' */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 148 0x94 '\224' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 149 0x95 '\225' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 150 0x96 '\226' */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 151 0x97 '\227' */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 152 0x98 '\230' */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 153 0x99 '\231' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 154 0x9a '\232' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 155 0x9b '\233' */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 156 0x9c '\234' */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 157 0x9d '\235' */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 158 0x9e '\236' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 159 0x9f '\237' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 160 0xa0 '\240' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 161 0xa1 '\241' */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 162 0xa2 '\242' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 163 0xa3 '\243' */ + 0xf00, /* 0000 00000000 */ + 0xf00, /* 0000 00000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3f00, /* 00 00000000 */ + 0x3f00, /* 00 00000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 164 0xa4 '\244' */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 165 0xa5 '\245' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 166 0xa6 '\246' */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 167 0xa7 '\247' */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 168 0xa8 '\250' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3f00, /* 00 00000000 */ + 0x3f00, /* 00 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 169 0xa9 '\251' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3f00, /* 00 00000000 */ + 0x3f00, /* 00 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xf30, /* 0000 00 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x3f00, /* 00 00000000 */ + 0x3f00, /* 00 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 170 0xaa '\252' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3fcc, /* 00 00 00 */ + 0x3fcc, /* 00 00 00 */ + 0xcfc, /* 0000 00 00 */ + 0xcfc, /* 0000 00 00 */ + 0xcfc, /* 0000 00 00 */ + 0xcfc, /* 0000 00 00 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 171 0xab '\253' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 172 0xac '\254' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 173 0xad '\255' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 174 0xae '\256' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3fc0, /* 00 000000 */ + 0x3fc0, /* 00 000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x33f0, /* 00 00 0000 */ + 0x33f0, /* 00 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 175 0xaf '\257' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 176 0xb0 '\260' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3cf0, /* 00 00 0000 */ + 0x3cf0, /* 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3cf0, /* 00 00 0000 */ + 0x3cf0, /* 00 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 177 0xb1 '\261' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 178 0xb2 '\262' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 179 0xb3 '\263' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3f0, /* 000000 0000 */ + 0x3f0, /* 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 180 0xb4 '\264' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 181 0xb5 '\265' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x3f30, /* 00 00 0000 */ + 0x3f30, /* 00 00 0000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 182 0xb6 '\266' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xf0, /* 00000000 0000 */ + 0xf0, /* 00000000 0000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 183 0xb7 '\267' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 184 0xb8 '\270' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 185 0xb9 '\271' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 186 0xba '\272' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3c00, /* 00 0000000000 */ + 0x3c00, /* 00 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 187 0xbb '\273' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3f0, /* 000000 0000 */ + 0x3f0, /* 000000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x3f0, /* 000000 0000 */ + 0x3f0, /* 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 188 0xbc '\274' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 189 0xbd '\275' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3cf0, /* 00 00 0000 */ + 0x3cf0, /* 00 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 190 0xbe '\276' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x33f0, /* 00 00 0000 */ + 0x33f0, /* 00 00 0000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 191 0xbf '\277' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x30f0, /* 00 0000 0000 */ + 0x30f0, /* 00 0000 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0x3c30, /* 00 0000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 192 0xc0 '\300' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 193 0xc1 '\301' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 194 0xc2 '\302' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 195 0xc3 '\303' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xf0, /* 00000000 0000 */ + 0xf0, /* 00000000 0000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0xc00, /* 0000 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 196 0xc4 '\304' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3c00, /* 00 0000000000 */ + 0x3c00, /* 00 0000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 197 0xc5 '\305' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3000, /* 00 000000000000 */ + 0x3000, /* 00 000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 198 0xc6 '\306' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 199 0xc7 '\307' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 200 0xc8 '\310' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0xc30, /* 0000 0000 0000 */ + 0x30c0, /* 00 0000 000000 */ + 0x30c0, /* 00 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 201 0xc9 '\311' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 202 0xca '\312' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 203 0xcb '\313' */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 204 0xcc '\314' */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 205 0xcd '\315' */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 206 0xce '\316' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x33c0, /* 00 00 000000 */ + 0x33c0, /* 00 00 000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 207 0xcf '\317' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3330, /* 00 00 00 0000 */ + 0x3330, /* 00 00 00 0000 */ + 0x33f0, /* 00 00 0000 */ + 0x33f0, /* 00 00 0000 */ + 0x3300, /* 00 00 00000000 */ + 0x3300, /* 00 00 00000000 */ + 0xcf0, /* 0000 00 0000 */ + 0xcf0, /* 0000 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 208 0xd0 '\320' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 209 0xd1 '\321' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ffc, /* 00 00 */ + 0x3ffc, /* 00 00 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 210 0xd2 '\322' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 211 0xd3 '\323' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0x330, /* 000000 00 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 212 0xd4 '\324' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 213 0xd5 '\325' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3c0, /* 000000 000000 */ + 0x3c0, /* 000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0xc0, /* 00000000 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 214 0xd6 '\326' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ff0, /* 00 0000 */ + 0x3ff0, /* 00 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 215 0xd7 '\327' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x300, /* 000000 00000000 */ + 0x300, /* 000000 00000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 216 0xd8 '\330' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xcc0, /* 0000 00 000000 */ + 0xcc0, /* 0000 00 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0x3030, /* 00 000000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x30, /* 0000000000 0000 */ + 0x30, /* 0000000000 0000 */ + 0xfc0, /* 0000 000000 */ + 0xfc0, /* 0000 000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 217 0xd9 '\331' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ffc, /* 00 00 */ + 0x3ffc, /* 00 00 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ffc, /* 00 00 */ + 0x3ffc, /* 00 00 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x3ffc, /* 00 00 */ + 0x3ffc, /* 00 00 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 218 0xda '\332' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 219 0xdb '\333' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 220 0xdc '\334' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 221 0xdd '\335' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 222 0xde '\336' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 223 0xdf '\337' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 224 0xe0 '\340' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 225 0xe1 '\341' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 226 0xe2 '\342' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 227 0xe3 '\343' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 228 0xe4 '\344' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 229 0xe5 '\345' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 230 0xe6 '\346' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 231 0xe7 '\347' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 232 0xe8 '\350' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 233 0xe9 '\351' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 234 0xea '\352' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 235 0xeb '\353' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 236 0xec '\354' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 237 0xed '\355' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 238 0xee '\356' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 239 0xef '\357' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 240 0xf0 '\360' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 241 0xf1 '\361' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 242 0xf2 '\362' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 243 0xf3 '\363' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 244 0xf4 '\364' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 245 0xf5 '\365' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 246 0xf6 '\366' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 247 0xf7 '\367' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 248 0xf8 '\370' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 249 0xf9 '\371' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 250 0xfa '\372' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 251 0xfb '\373' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 252 0xfc '\374' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 253 0xfd '\375' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 254 0xfe '\376' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + + /* 255 0xff '\377' */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0xff0, /* 0000 0000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ + 0x0, /* 0000000000000000 */ }; diff --git a/src/zm_box.h b/src/zm_box.h index 8aa341d73..f5fe69a38 100644 --- a/src/zm_box.h +++ b/src/zm_box.h @@ -36,39 +36,39 @@ class Box { private: - Coord lo, hi; - Coord size; + Coord lo, hi; + Coord size; public: - inline Box() - { - } - inline Box( int p_size ) : lo( 0, 0 ), hi ( p_size-1, p_size-1 ), size( Coord::Range( hi, lo ) ) { } - inline Box( int p_x_size, int p_y_size ) : lo( 0, 0 ), hi ( p_x_size-1, p_y_size-1 ), size( Coord::Range( hi, lo ) ) { } - inline Box( int lo_x, int lo_y, int hi_x, int hi_y ) : lo( lo_x, lo_y ), hi( hi_x, hi_y ), size( Coord::Range( hi, lo ) ) { } - inline Box( const Coord &p_lo, const Coord &p_hi ) : lo( p_lo ), hi( p_hi ), size( Coord::Range( hi, lo ) ) { } + inline Box() + { + } + inline Box( int p_size ) : lo( 0, 0 ), hi ( p_size-1, p_size-1 ), size( Coord::Range( hi, lo ) ) { } + inline Box( int p_x_size, int p_y_size ) : lo( 0, 0 ), hi ( p_x_size-1, p_y_size-1 ), size( Coord::Range( hi, lo ) ) { } + inline Box( int lo_x, int lo_y, int hi_x, int hi_y ) : lo( lo_x, lo_y ), hi( hi_x, hi_y ), size( Coord::Range( hi, lo ) ) { } + inline Box( const Coord &p_lo, const Coord &p_hi ) : lo( p_lo ), hi( p_hi ), size( Coord::Range( hi, lo ) ) { } - inline const Coord &Lo() const { return( lo ); } - inline int LoX() const { return( lo.X() ); } - inline int LoY() const { return( lo.Y() ); } - inline const Coord &Hi() const { return( hi ); } - inline int HiX() const { return( hi.X() ); } - inline int HiY() const { return( hi.Y() ); } - inline const Coord &Size() const { return( size ); } - inline int Width() const { return( size.X() ); } - inline int Height() const { return( size.Y() ); } - inline int Area() const { return( size.X()*size.Y() ); } + inline const Coord &Lo() const { return( lo ); } + inline int LoX() const { return( lo.X() ); } + inline int LoY() const { return( lo.Y() ); } + inline const Coord &Hi() const { return( hi ); } + inline int HiX() const { return( hi.X() ); } + inline int HiY() const { return( hi.Y() ); } + inline const Coord &Size() const { return( size ); } + inline int Width() const { return( size.X() ); } + inline int Height() const { return( size.Y() ); } + inline int Area() const { return( size.X()*size.Y() ); } - inline const Coord Centre() const - { - int mid_x = int(round(lo.X()+(size.X()/2.0))); - int mid_y = int(round(lo.Y()+(size.Y()/2.0))); - return( Coord( mid_x, mid_y ) ); - } - inline bool Inside( const Coord &coord ) const - { - return( coord.X() >= lo.X() && coord.X() <= hi.X() && coord.Y() >= lo.Y() && coord.Y() <= hi.Y() ); - } + inline const Coord Centre() const + { + int mid_x = int(round(lo.X()+(size.X()/2.0))); + int mid_y = int(round(lo.Y()+(size.Y()/2.0))); + return( Coord( mid_x, mid_y ) ); + } + inline bool Inside( const Coord &coord ) const + { + return( coord.X() >= lo.X() && coord.X() <= hi.X() && coord.Y() >= lo.Y() && coord.Y() <= hi.Y() ); + } }; #endif // ZM_BOX_H diff --git a/src/zm_buffer.cpp b/src/zm_buffer.cpp index d2fb2ef72..b46cb2f15 100644 --- a/src/zm_buffer.cpp +++ b/src/zm_buffer.cpp @@ -25,57 +25,57 @@ unsigned int Buffer::assign( const unsigned char *pStorage, unsigned int pSize ) { - if ( mAllocation < pSize ) - { - delete[] mStorage; - mAllocation = pSize; - mHead = mStorage = new unsigned char[pSize]; - } - mSize = pSize; - memcpy( mStorage, pStorage, mSize ); - mHead = mStorage; - mTail = mHead + mSize; - return( mSize ); + if ( mAllocation < pSize ) + { + delete[] mStorage; + mAllocation = pSize; + mHead = mStorage = new unsigned char[pSize]; + } + mSize = pSize; + memcpy( mStorage, pStorage, mSize ); + mHead = mStorage; + mTail = mHead + mSize; + return( mSize ); } unsigned int Buffer::expand( unsigned int count ) { - int spare = mAllocation - mSize; - int headSpace = mHead - mStorage; - int tailSpace = spare - headSpace; - int width = mTail - mHead; - if ( spare > (int)count ) + int spare = mAllocation - mSize; + int headSpace = mHead - mStorage; + int tailSpace = spare - headSpace; + int width = mTail - mHead; + if ( spare > (int)count ) + { + if ( tailSpace < (int)count ) { - if ( tailSpace < (int)count ) - { - memmove( mStorage, mHead, mSize ); - mHead = mStorage; - mTail = mHead + width; - } + memmove( mStorage, mHead, mSize ); + mHead = mStorage; + mTail = mHead + width; } - else + } + else + { + mAllocation += count; + unsigned char *newStorage = new unsigned char[mAllocation]; + if ( mStorage ) { - mAllocation += count; - unsigned char *newStorage = new unsigned char[mAllocation]; - if ( mStorage ) - { - memcpy( newStorage, mHead, mSize ); - delete[] mStorage; - } - mStorage = newStorage; - mHead = mStorage; - mTail = mHead + width; + memcpy( newStorage, mHead, mSize ); + delete[] mStorage; } - return( mSize ); + mStorage = newStorage; + mHead = mStorage; + mTail = mHead + width; + } + return( mSize ); } int Buffer::read_into( int sd, unsigned int bytes ) { - // Make sure there is enough space - this->expand(bytes); - int bytes_read = read( sd, mTail, bytes ); - if ( bytes_read > 0 ) { - mTail += bytes_read; - mSize += bytes_read; - } - return bytes_read; + // Make sure there is enough space + this->expand(bytes); + int bytes_read = read( sd, mTail, bytes ); + if ( bytes_read > 0 ) { + mTail += bytes_read; + mSize += bytes_read; + } + return bytes_read; } diff --git a/src/zm_buffer.h b/src/zm_buffer.h index 007df4459..620fce1a8 100644 --- a/src/zm_buffer.h +++ b/src/zm_buffer.h @@ -27,183 +27,183 @@ class Buffer { protected: - unsigned char *mStorage; - unsigned int mAllocation; - unsigned int mSize; - unsigned char *mHead; - unsigned char *mTail; + unsigned char *mStorage; + unsigned int mAllocation; + unsigned int mSize; + unsigned char *mHead; + unsigned char *mTail; public: - Buffer() : mStorage( 0 ), mAllocation( 0 ), mSize( 0 ), mHead( 0 ), mTail( 0 ) + Buffer() : mStorage( 0 ), mAllocation( 0 ), mSize( 0 ), mHead( 0 ), mTail( 0 ) + { + } + Buffer( unsigned int pSize ) : mAllocation( pSize ), mSize( 0 ) + { + mHead = mStorage = new unsigned char[mAllocation]; + mTail = mHead; + } + Buffer( const unsigned char *pStorage, unsigned int pSize ) : mAllocation( pSize ), mSize( pSize ) + { + mHead = mStorage = new unsigned char[mSize]; + memcpy( mStorage, pStorage, mSize ); + mTail = mHead + mSize; + } + Buffer( const Buffer &buffer ) : mAllocation( buffer.mSize ), mSize( buffer.mSize ) + { + mHead = mStorage = new unsigned char[mSize]; + memcpy( mStorage, buffer.mHead, mSize ); + mTail = mHead + mSize; + } + ~Buffer() + { + delete[] mStorage; + } + unsigned char *head() const { return( mHead ); } + unsigned char *tail() const { return( mTail ); } + unsigned int size() const { return( mSize ); } + bool empty() const { return( mSize == 0 ); } + unsigned int size( unsigned int pSize ) + { + if ( mSize < pSize ) { + expand( pSize-mSize ); } - Buffer( unsigned int pSize ) : mAllocation( pSize ), mSize( 0 ) - { - mHead = mStorage = new unsigned char[mAllocation]; - mTail = mHead; - } - Buffer( const unsigned char *pStorage, unsigned int pSize ) : mAllocation( pSize ), mSize( pSize ) - { - mHead = mStorage = new unsigned char[mSize]; - memcpy( mStorage, pStorage, mSize ); - mTail = mHead + mSize; - } - Buffer( const Buffer &buffer ) : mAllocation( buffer.mSize ), mSize( buffer.mSize ) - { - mHead = mStorage = new unsigned char[mSize]; - memcpy( mStorage, buffer.mHead, mSize ); - mTail = mHead + mSize; - } - ~Buffer() - { - delete[] mStorage; - } - unsigned char *head() const { return( mHead ); } - unsigned char *tail() const { return( mTail ); } - unsigned int size() const { return( mSize ); } - bool empty() const { return( mSize == 0 ); } - unsigned int size( unsigned int pSize ) - { - if ( mSize < pSize ) - { - expand( pSize-mSize ); - } - return( mSize ); - } - //unsigned int Allocation() const { return( mAllocation ); } + return( mSize ); + } + //unsigned int Allocation() const { return( mAllocation ); } - void clear() + void clear() + { + mSize = 0; + mHead = mTail = mStorage; + } + + unsigned int assign( const unsigned char *pStorage, unsigned int pSize ); + unsigned int assign( const Buffer &buffer ) + { + return( assign( buffer.mHead, buffer.mSize ) ); + } + + // Trim from the front of the buffer + unsigned int consume( unsigned int count ) + { + if ( count > mSize ) { - mSize = 0; + Warning( "Attempt to consume %d bytes of buffer, size is only %d bytes", count, mSize ); + count = mSize; + } + mHead += count; + mSize -= count; + tidy( 0 ); + return( count ); + } + // Trim from the end of the buffer + unsigned int shrink( unsigned int count ) + { + if ( count > mSize ) + { + Warning( "Attempt to shrink buffer by %d bytes, size is only %d bytes", count, mSize ); + count = mSize; + } + mSize -= count; + if ( mTail > (mHead + mSize) ) + mTail = mHead + mSize; + tidy( 0 ); + return( count ); + } + // Add to the end of the buffer + unsigned int expand( unsigned int count ); + + // Return pointer to the first pSize bytes and advance the head + unsigned char *extract( unsigned int pSize ) + { + if ( pSize > mSize ) + { + Warning( "Attempt to extract %d bytes of buffer, size is only %d bytes", pSize, mSize ); + pSize = mSize; + } + unsigned char *oldHead = mHead; + mHead += pSize; + mSize -= pSize; + tidy( 0 ); + return( oldHead ); + } + // Add bytes to the end of the buffer + unsigned int append( const unsigned char *pStorage, unsigned int pSize ) + { + expand( pSize ); + memcpy( mTail, pStorage, pSize ); + mTail += pSize; + mSize += pSize; + return( mSize ); + } + unsigned int append( const char *pStorage, unsigned int pSize ) + { + return( append( (const unsigned char *)pStorage, pSize ) ); + } + unsigned int append( const Buffer &buffer ) + { + return( append( buffer.mHead, buffer.mSize ) ); + } + void tidy( bool level=0 ) + { + if ( mHead != mStorage ) + { + if ( mSize == 0 ) mHead = mTail = mStorage; - } - - unsigned int assign( const unsigned char *pStorage, unsigned int pSize ); - unsigned int assign( const Buffer &buffer ) - { - return( assign( buffer.mHead, buffer.mSize ) ); - } - - // Trim from the front of the buffer - unsigned int consume( unsigned int count ) - { - if ( count > mSize ) + else if ( level ) + { + if ( (mHead-mStorage) > mSize ) { - Warning( "Attempt to consume %d bytes of buffer, size is only %d bytes", count, mSize ); - count = mSize; + memcpy( mStorage, mHead, mSize ); + mHead = mStorage; + mTail = mHead + mSize; } - mHead += count; - mSize -= count; - tidy( 0 ); - return( count ); + } } - // Trim from the end of the buffer - unsigned int shrink( unsigned int count ) - { - if ( count > mSize ) - { - Warning( "Attempt to shrink buffer by %d bytes, size is only %d bytes", count, mSize ); - count = mSize; - } - mSize -= count; - if ( mTail > (mHead + mSize) ) - mTail = mHead + mSize; - tidy( 0 ); - return( count ); - } - // Add to the end of the buffer - unsigned int expand( unsigned int count ); + } - // Return pointer to the first pSize bytes and advance the head - unsigned char *extract( unsigned int pSize ) - { - if ( pSize > mSize ) - { - Warning( "Attempt to extract %d bytes of buffer, size is only %d bytes", pSize, mSize ); - pSize = mSize; - } - unsigned char *oldHead = mHead; - mHead += pSize; - mSize -= pSize; - tidy( 0 ); - return( oldHead ); - } - // Add bytes to the end of the buffer - unsigned int append( const unsigned char *pStorage, unsigned int pSize ) - { - expand( pSize ); - memcpy( mTail, pStorage, pSize ); - mTail += pSize; - mSize += pSize; - return( mSize ); - } - unsigned int append( const char *pStorage, unsigned int pSize ) - { - return( append( (const unsigned char *)pStorage, pSize ) ); - } - unsigned int append( const Buffer &buffer ) - { - return( append( buffer.mHead, buffer.mSize ) ); - } - void tidy( bool level=0 ) - { - if ( mHead != mStorage ) - { - if ( mSize == 0 ) - mHead = mTail = mStorage; - else if ( level ) - { - if ( (mHead-mStorage) > mSize ) - { - memcpy( mStorage, mHead, mSize ); - mHead = mStorage; - mTail = mHead + mSize; - } - } - } - } - - Buffer &operator=( const Buffer &buffer ) - { - assign( buffer ); - return( *this ); - } - Buffer &operator+=( const Buffer &buffer ) - { - append( buffer ); - return( *this ); - } - Buffer &operator+=( unsigned int count ) - { - expand( count ); - return( *this ); - } - Buffer &operator-=( unsigned int count ) - { - consume( count ); - return( *this ); - } - operator unsigned char *() const - { - return( mHead ); - } - operator char *() const - { - return( (char *)mHead ); - } - unsigned char *operator+(int offset) const - { - return( (unsigned char *)(mHead+offset) ); - } - unsigned char operator[](int index) const - { - return( *(mHead+index) ); - } - operator int () const - { - return( (int)mSize ); - } - int read_into( int sd, unsigned int bytes ); + Buffer &operator=( const Buffer &buffer ) + { + assign( buffer ); + return( *this ); + } + Buffer &operator+=( const Buffer &buffer ) + { + append( buffer ); + return( *this ); + } + Buffer &operator+=( unsigned int count ) + { + expand( count ); + return( *this ); + } + Buffer &operator-=( unsigned int count ) + { + consume( count ); + return( *this ); + } + operator unsigned char *() const + { + return( mHead ); + } + operator char *() const + { + return( (char *)mHead ); + } + unsigned char *operator+(int offset) const + { + return( (unsigned char *)(mHead+offset) ); + } + unsigned char operator[](int index) const + { + return( *(mHead+index) ); + } + operator int () const + { + return( (int)mSize ); + } + int read_into( int sd, unsigned int bytes ); }; #endif // ZM_BUFFER_H diff --git a/src/zm_comms.cpp b/src/zm_comms.cpp index a109019bd..1fd224b18 100644 --- a/src/zm_comms.cpp +++ b/src/zm_comms.cpp @@ -42,89 +42,89 @@ int CommsBase::readV( int iovcnt, /* const void *, int, */ ... ) { - va_list arg_ptr; - //struct iovec iov[iovcnt]; - struct iovec *iov = (struct iovec *)alloca( sizeof(struct iovec)*iovcnt ); + va_list arg_ptr; + //struct iovec iov[iovcnt]; + struct iovec *iov = (struct iovec *)alloca( sizeof(struct iovec)*iovcnt ); - va_start( arg_ptr, iovcnt ); - for ( int i = 0; i < iovcnt; i++ ) - { - iov[i].iov_base = va_arg( arg_ptr, void * ); - iov[i].iov_len = va_arg( arg_ptr, int ); - } - va_end( arg_ptr ); + va_start( arg_ptr, iovcnt ); + for ( int i = 0; i < iovcnt; i++ ) + { + iov[i].iov_base = va_arg( arg_ptr, void * ); + iov[i].iov_len = va_arg( arg_ptr, int ); + } + va_end( arg_ptr ); - int nBytes = ::readv( mRd, iov, iovcnt ); - if ( nBytes < 0 ) - Debug( 1, "Readv of %d buffers max on rd %d failed: %s", iovcnt, mRd, strerror(errno) ); - return( nBytes ); + int nBytes = ::readv( mRd, iov, iovcnt ); + if ( nBytes < 0 ) + Debug( 1, "Readv of %d buffers max on rd %d failed: %s", iovcnt, mRd, strerror(errno) ); + return( nBytes ); } int CommsBase::writeV( int iovcnt, /* const void *, int, */ ... ) { - va_list arg_ptr; - //struct iovec iov[iovcnt]; - struct iovec *iov = (struct iovec *)alloca( sizeof(struct iovec)*iovcnt ); + va_list arg_ptr; + //struct iovec iov[iovcnt]; + struct iovec *iov = (struct iovec *)alloca( sizeof(struct iovec)*iovcnt ); - va_start( arg_ptr, iovcnt ); - for ( int i = 0; i < iovcnt; i++ ) - { - iov[i].iov_base = va_arg( arg_ptr, void * ); - iov[i].iov_len = va_arg( arg_ptr, int ); - } - va_end( arg_ptr ); + va_start( arg_ptr, iovcnt ); + for ( int i = 0; i < iovcnt; i++ ) + { + iov[i].iov_base = va_arg( arg_ptr, void * ); + iov[i].iov_len = va_arg( arg_ptr, int ); + } + va_end( arg_ptr ); - ssize_t nBytes = ::writev( mWd, iov, iovcnt ); - if ( nBytes < 0 ) - Debug( 1, "Writev of %d buffers on wd %d failed: %s", iovcnt, mWd, strerror(errno) ); - return( nBytes ); + ssize_t nBytes = ::writev( mWd, iov, iovcnt ); + if ( nBytes < 0 ) + Debug( 1, "Writev of %d buffers on wd %d failed: %s", iovcnt, mWd, strerror(errno) ); + return( nBytes ); } bool Pipe::open() { - if ( ::pipe( mFd ) < 0 ) - { - Error( "pipe(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } + if ( ::pipe( mFd ) < 0 ) + { + Error( "pipe(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } - return( true ); + return( true ); } bool Pipe::close() { - if ( mFd[0] > -1 ) ::close( mFd[0] ); - mFd[0] = -1; - if ( mFd[1] > -1 ) ::close( mFd[1] ); - mFd[1] = -1; - return( true ); + if ( mFd[0] > -1 ) ::close( mFd[0] ); + mFd[0] = -1; + if ( mFd[1] > -1 ) ::close( mFd[1] ); + mFd[1] = -1; + return( true ); } bool Pipe::setBlocking( bool blocking ) { - int flags; + int flags; - /* Now set it for non-blocking I/O */ - if ( (flags = fcntl( mFd[1], F_GETFL )) < 0 ) - { - Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - if ( blocking ) - { - flags &= ~O_NONBLOCK; - } - else - { - flags |= O_NONBLOCK; - } - if ( fcntl( mFd[1], F_SETFL, flags ) < 0 ) - { - Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } + /* Now set it for non-blocking I/O */ + if ( (flags = fcntl( mFd[1], F_GETFL )) < 0 ) + { + Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + if ( blocking ) + { + flags &= ~O_NONBLOCK; + } + else + { + flags |= O_NONBLOCK; + } + if ( fcntl( mFd[1], F_SETFL, flags ) < 0 ) + { + Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } - return( true ); + return( true ); } SockAddr::SockAddr( const struct sockaddr *addr ) : mAddr( addr ) @@ -133,33 +133,33 @@ SockAddr::SockAddr( const struct sockaddr *addr ) : mAddr( addr ) SockAddr *SockAddr::newSockAddr( const struct sockaddr &addr, socklen_t len ) { - if ( addr.sa_family == AF_INET && len == SockAddrInet::addrSize() ) - { - return( new SockAddrInet( (const struct sockaddr_in *)&addr ) ); - } - else if ( addr.sa_family == AF_UNIX && len == SockAddrUnix::addrSize() ) - { - return( new SockAddrUnix( (const struct sockaddr_un *)&addr ) ); - } - Error( "Unable to create new SockAddr from addr family %d with size %d", addr.sa_family, len ); - return( 0 ); + if ( addr.sa_family == AF_INET && len == SockAddrInet::addrSize() ) + { + return( new SockAddrInet( (const struct sockaddr_in *)&addr ) ); + } + else if ( addr.sa_family == AF_UNIX && len == SockAddrUnix::addrSize() ) + { + return( new SockAddrUnix( (const struct sockaddr_un *)&addr ) ); + } + Error( "Unable to create new SockAddr from addr family %d with size %d", addr.sa_family, len ); + return( 0 ); } SockAddr *SockAddr::newSockAddr( const SockAddr *addr ) { - if ( !addr ) - return( 0 ); - - if ( addr->getDomain() == AF_INET ) - { - return( new SockAddrInet( *(SockAddrInet *)addr ) ); - } - else if ( addr->getDomain() == AF_UNIX ) - { - return( new SockAddrUnix( *(SockAddrUnix *)addr ) ); - } - Error( "Unable to create new SockAddr from addr family %d", addr->getDomain() ); + if ( !addr ) return( 0 ); + + if ( addr->getDomain() == AF_INET ) + { + return( new SockAddrInet( *(SockAddrInet *)addr ) ); + } + else if ( addr->getDomain() == AF_UNIX ) + { + return( new SockAddrUnix( *(SockAddrUnix *)addr ) ); + } + Error( "Unable to create new SockAddr from addr family %d", addr->getDomain() ); + return( 0 ); } SockAddrInet::SockAddrInet() : SockAddr( (struct sockaddr *)&mAddrIn ) @@ -168,73 +168,73 @@ SockAddrInet::SockAddrInet() : SockAddr( (struct sockaddr *)&mAddrIn ) bool SockAddrInet::resolve( const char *host, const char *serv, const char *proto ) { - memset( &mAddrIn, 0, sizeof(mAddrIn) ); + memset( &mAddrIn, 0, sizeof(mAddrIn) ); - struct hostent *hostent=0; - if ( !(hostent = ::gethostbyname( host ) ) ) - { - Error( "gethostbyname( %s ), h_errno = %d", host, h_errno ); - return( false ); - } + struct hostent *hostent=0; + if ( !(hostent = ::gethostbyname( host ) ) ) + { + Error( "gethostbyname( %s ), h_errno = %d", host, h_errno ); + return( false ); + } - struct servent *servent=0; - if ( !(servent = ::getservbyname( serv, proto ) ) ) - { - Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) ); - return( false ); - } + struct servent *servent=0; + if ( !(servent = ::getservbyname( serv, proto ) ) ) + { + Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) ); + return( false ); + } - mAddrIn.sin_port = servent->s_port; - mAddrIn.sin_family = AF_INET; - mAddrIn.sin_addr.s_addr = ((struct in_addr *)(hostent->h_addr))->s_addr; + mAddrIn.sin_port = servent->s_port; + mAddrIn.sin_family = AF_INET; + mAddrIn.sin_addr.s_addr = ((struct in_addr *)(hostent->h_addr))->s_addr; - return( true ); + return( true ); } bool SockAddrInet::resolve( const char *host, int port, const char *proto ) { - memset( &mAddrIn, 0, sizeof(mAddrIn) ); + memset( &mAddrIn, 0, sizeof(mAddrIn) ); - struct hostent *hostent=0; - if ( !(hostent = ::gethostbyname( host ) ) ) - { - Error( "gethostbyname( %s ), h_errno = %d", host, h_errno ); - return( false ); - } + struct hostent *hostent=0; + if ( !(hostent = ::gethostbyname( host ) ) ) + { + Error( "gethostbyname( %s ), h_errno = %d", host, h_errno ); + return( false ); + } - mAddrIn.sin_port = htons(port); - mAddrIn.sin_family = AF_INET; - mAddrIn.sin_addr.s_addr = ((struct in_addr *)(hostent->h_addr))->s_addr; - return( true ); + mAddrIn.sin_port = htons(port); + mAddrIn.sin_family = AF_INET; + mAddrIn.sin_addr.s_addr = ((struct in_addr *)(hostent->h_addr))->s_addr; + return( true ); } bool SockAddrInet::resolve( const char *serv, const char *proto ) { - memset( &mAddrIn, 0, sizeof(mAddrIn) ); + memset( &mAddrIn, 0, sizeof(mAddrIn) ); - struct servent *servent=0; - if ( !(servent = ::getservbyname( serv, proto ) ) ) - { - Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) ); - return( false ); - } + struct servent *servent=0; + if ( !(servent = ::getservbyname( serv, proto ) ) ) + { + Error( "getservbyname( %s ), errno = %d, error = %s", serv, errno, strerror(errno) ); + return( false ); + } - mAddrIn.sin_port = servent->s_port; - mAddrIn.sin_family = AF_INET; - mAddrIn.sin_addr.s_addr = INADDR_ANY; + mAddrIn.sin_port = servent->s_port; + mAddrIn.sin_family = AF_INET; + mAddrIn.sin_addr.s_addr = INADDR_ANY; - return( true ); + return( true ); } bool SockAddrInet::resolve( int port, const char *proto ) { - memset( &mAddrIn, 0, sizeof(mAddrIn) ); + memset( &mAddrIn, 0, sizeof(mAddrIn) ); - mAddrIn.sin_port = htons(port); - mAddrIn.sin_family = AF_INET; - mAddrIn.sin_addr.s_addr = INADDR_ANY; + mAddrIn.sin_port = htons(port); + mAddrIn.sin_family = AF_INET; + mAddrIn.sin_addr.s_addr = INADDR_ANY; - return( true ); + return( true ); } SockAddrUnix::SockAddrUnix() : SockAddr( (struct sockaddr *)&mAddrUn ) @@ -243,313 +243,313 @@ SockAddrUnix::SockAddrUnix() : SockAddr( (struct sockaddr *)&mAddrUn ) bool SockAddrUnix::resolve( const char *path, const char *proto ) { - memset( &mAddrUn, 0, sizeof(mAddrUn) ); + memset( &mAddrUn, 0, sizeof(mAddrUn) ); - strncpy( mAddrUn.sun_path, path, sizeof(mAddrUn.sun_path) ); - mAddrUn.sun_family = AF_UNIX; + strncpy( mAddrUn.sun_path, path, sizeof(mAddrUn.sun_path) ); + mAddrUn.sun_family = AF_UNIX; - return( true ); + return( true ); } bool Socket::socket() { - if ( mSd >= 0 ) - return( true ); + if ( mSd >= 0 ) + return( true ); - if ( (mSd = ::socket( getDomain(), getType(), 0 ) ) < 0 ) - { - Error( "socket(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } + if ( (mSd = ::socket( getDomain(), getType(), 0 ) ) < 0 ) + { + Error( "socket(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } - int val = 1; + int val = 1; - (void)::setsockopt( mSd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val) ); - (void)::setsockopt( mSd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val) ); + (void)::setsockopt( mSd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val) ); + (void)::setsockopt( mSd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val) ); - mState = DISCONNECTED; + mState = DISCONNECTED; - return( true ); + return( true ); } bool Socket::connect() { - if ( !socket() ) - return( false ); + if ( !socket() ) + return( false ); - if ( ::connect( mSd, mRemoteAddr->getAddr(), getAddrSize() ) == -1 ) - { - Error( "connect(), errno = %d, error = %s", errno, strerror(errno) ); - close(); - return( false ); - } + if ( ::connect( mSd, mRemoteAddr->getAddr(), getAddrSize() ) == -1 ) + { + Error( "connect(), errno = %d, error = %s", errno, strerror(errno) ); + close(); + return( false ); + } - mState = CONNECTED; + mState = CONNECTED; - return( true ); + return( true ); } bool Socket::bind() { - if ( !socket() ) - return( false ); + if ( !socket() ) + return( false ); - if ( ::bind( mSd, mLocalAddr->getAddr(), getAddrSize() ) == -1 ) - { - Error( "bind(), errno = %d, error = %s", errno, strerror(errno) ); - close(); - return( false ); - } - return( true ); + if ( ::bind( mSd, mLocalAddr->getAddr(), getAddrSize() ) == -1 ) + { + Error( "bind(), errno = %d, error = %s", errno, strerror(errno) ); + close(); + return( false ); + } + return( true ); } bool Socket::listen() { - if ( ::listen( mSd, SOMAXCONN ) == -1 ) - { - Error( "listen(), errno = %d, error = %s", errno, strerror(errno) ); - close(); - return( false ); - } + if ( ::listen( mSd, SOMAXCONN ) == -1 ) + { + Error( "listen(), errno = %d, error = %s", errno, strerror(errno) ); + close(); + return( false ); + } - mState = LISTENING; + mState = LISTENING; - return( true ); + return( true ); } bool Socket::accept() { - struct sockaddr *rem_addr = mLocalAddr->getTempAddr(); - socklen_t rem_addr_size = getAddrSize(); + struct sockaddr *rem_addr = mLocalAddr->getTempAddr(); + socklen_t rem_addr_size = getAddrSize(); - int newSd = -1; - if ( (newSd = ::accept( mSd, rem_addr, &rem_addr_size )) == -1 ) - { - Error( "accept(), errno = %d, error = %s", errno, strerror(errno) ); - close(); - return( false ); - } + int newSd = -1; + if ( (newSd = ::accept( mSd, rem_addr, &rem_addr_size )) == -1 ) + { + Error( "accept(), errno = %d, error = %s", errno, strerror(errno) ); + close(); + return( false ); + } - ::close( mSd ); - mSd = newSd; + ::close( mSd ); + mSd = newSd; - mState = CONNECTED; + mState = CONNECTED; - return( true ); + return( true ); } bool Socket::accept( int &newSd ) { - struct sockaddr *rem_addr = mLocalAddr->getTempAddr(); - socklen_t rem_addr_size = getAddrSize(); + struct sockaddr *rem_addr = mLocalAddr->getTempAddr(); + socklen_t rem_addr_size = getAddrSize(); - newSd = -1; - if ( (newSd = ::accept( mSd, rem_addr, &rem_addr_size )) == -1 ) - { - Error( "accept(), errno = %d, error = %s", errno, strerror(errno) ); - close(); - return( false ); - } + newSd = -1; + if ( (newSd = ::accept( mSd, rem_addr, &rem_addr_size )) == -1 ) + { + Error( "accept(), errno = %d, error = %s", errno, strerror(errno) ); + close(); + return( false ); + } - return( true ); + return( true ); } bool Socket::close() { - if ( mSd > -1 ) ::close( mSd ); - mSd = -1; - mState = CLOSED; - return( true ); + if ( mSd > -1 ) ::close( mSd ); + mSd = -1; + mState = CLOSED; + return( true ); } int Socket::bytesToRead() const { - int bytes_to_read = 0; + int bytes_to_read = 0; - if ( ioctl( mSd, FIONREAD, &bytes_to_read ) < 0 ) - { - Error( "ioctl(), errno = %d, error = %s", errno, strerror(errno) ); - return( -1 ); - } - return( bytes_to_read ); + if ( ioctl( mSd, FIONREAD, &bytes_to_read ) < 0 ) + { + Error( "ioctl(), errno = %d, error = %s", errno, strerror(errno) ); + return( -1 ); + } + return( bytes_to_read ); } bool Socket::getBlocking( bool &blocking ) { - int flags; + int flags; - if ( (flags = fcntl( mSd, F_GETFL )) < 0 ) - { - Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - blocking = (flags & O_NONBLOCK); - return( true ); + if ( (flags = fcntl( mSd, F_GETFL )) < 0 ) + { + Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + blocking = (flags & O_NONBLOCK); + return( true ); } bool Socket::setBlocking( bool blocking ) { #if 0 - // ioctl is apparently not recommended - int ioctl_arg = !blocking; - if ( ioctl( mSd, FIONBIO, &ioctl_arg ) < 0 ) - { - Error( "ioctl(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - return( true ); + // ioctl is apparently not recommended + int ioctl_arg = !blocking; + if ( ioctl( mSd, FIONBIO, &ioctl_arg ) < 0 ) + { + Error( "ioctl(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + return( true ); #endif - int flags; + int flags; - /* Now set it for non-blocking I/O */ - if ( (flags = fcntl( mSd, F_GETFL )) < 0 ) - { - Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - if ( blocking ) - { - flags &= ~O_NONBLOCK; - } - else - { - flags |= O_NONBLOCK; - } - if ( fcntl( mSd, F_SETFL, flags ) < 0 ) - { - Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } + /* Now set it for non-blocking I/O */ + if ( (flags = fcntl( mSd, F_GETFL )) < 0 ) + { + Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + if ( blocking ) + { + flags &= ~O_NONBLOCK; + } + else + { + flags |= O_NONBLOCK; + } + if ( fcntl( mSd, F_SETFL, flags ) < 0 ) + { + Error( "fcntl(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } - return( true ); + return( true ); } bool Socket::getSendBufferSize( int &buffersize ) const { - socklen_t optlen = sizeof(buffersize); - if ( getsockopt( mSd, SOL_SOCKET, SO_SNDBUF, &buffersize, &optlen ) < 0 ) - { - Error( "getsockopt(), errno = %d, error = %s", errno, strerror(errno) ); - return( -1 ); - } - return( buffersize ); + socklen_t optlen = sizeof(buffersize); + if ( getsockopt( mSd, SOL_SOCKET, SO_SNDBUF, &buffersize, &optlen ) < 0 ) + { + Error( "getsockopt(), errno = %d, error = %s", errno, strerror(errno) ); + return( -1 ); + } + return( buffersize ); } bool Socket::getRecvBufferSize( int &buffersize ) const { - socklen_t optlen = sizeof(buffersize); - if ( getsockopt( mSd, SOL_SOCKET, SO_RCVBUF, &buffersize, &optlen ) < 0 ) - { - Error( "getsockopt(), errno = %d, error = %s", errno, strerror(errno) ); - return( -1 ); - } - return( buffersize ); + socklen_t optlen = sizeof(buffersize); + if ( getsockopt( mSd, SOL_SOCKET, SO_RCVBUF, &buffersize, &optlen ) < 0 ) + { + Error( "getsockopt(), errno = %d, error = %s", errno, strerror(errno) ); + return( -1 ); + } + return( buffersize ); } bool Socket::setSendBufferSize( int buffersize ) { - if ( setsockopt( mSd, SOL_SOCKET, SO_SNDBUF, (char *)&buffersize, sizeof(buffersize)) < 0 ) - { - Error( "setsockopt(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - return( true ); + if ( setsockopt( mSd, SOL_SOCKET, SO_SNDBUF, (char *)&buffersize, sizeof(buffersize)) < 0 ) + { + Error( "setsockopt(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + return( true ); } bool Socket::setRecvBufferSize( int buffersize ) { - if ( setsockopt( mSd, SOL_SOCKET, SO_RCVBUF, (char *)&buffersize, sizeof(buffersize)) < 0 ) - { - Error( "setsockopt(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - return( true ); + if ( setsockopt( mSd, SOL_SOCKET, SO_RCVBUF, (char *)&buffersize, sizeof(buffersize)) < 0 ) + { + Error( "setsockopt(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + return( true ); } bool Socket::getRouting( bool &route ) const { - int dontRoute; - socklen_t optlen = sizeof(dontRoute); - if ( getsockopt( mSd, SOL_SOCKET, SO_DONTROUTE, &dontRoute, &optlen ) < 0 ) - { - Error( "getsockopt(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - route = !dontRoute; - return( true ); + int dontRoute; + socklen_t optlen = sizeof(dontRoute); + if ( getsockopt( mSd, SOL_SOCKET, SO_DONTROUTE, &dontRoute, &optlen ) < 0 ) + { + Error( "getsockopt(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + route = !dontRoute; + return( true ); } bool Socket::setRouting( bool route ) { - int dontRoute = !route; - if ( setsockopt( mSd, SOL_SOCKET, SO_DONTROUTE, (char *)&dontRoute, sizeof(dontRoute)) < 0 ) - { - Error( "setsockopt(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - return( true ); + int dontRoute = !route; + if ( setsockopt( mSd, SOL_SOCKET, SO_DONTROUTE, (char *)&dontRoute, sizeof(dontRoute)) < 0 ) + { + Error( "setsockopt(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + return( true ); } bool Socket::getNoDelay( bool &nodelay ) const { - int int_nodelay; - socklen_t optlen = sizeof(int_nodelay); - if ( getsockopt( mSd, IPPROTO_TCP, TCP_NODELAY, &int_nodelay, &optlen ) < 0 ) - { - Error( "getsockopt(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - nodelay = int_nodelay; - return( true ); + int int_nodelay; + socklen_t optlen = sizeof(int_nodelay); + if ( getsockopt( mSd, IPPROTO_TCP, TCP_NODELAY, &int_nodelay, &optlen ) < 0 ) + { + Error( "getsockopt(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + nodelay = int_nodelay; + return( true ); } bool Socket::setNoDelay( bool nodelay ) { - int int_nodelay = nodelay; + int int_nodelay = nodelay; - if ( setsockopt( mSd, IPPROTO_TCP, TCP_NODELAY, (char *)&int_nodelay, sizeof(int_nodelay)) < 0 ) - { - Error( "setsockopt(), errno = %d, error = %s", errno, strerror(errno) ); - return( false ); - } - return( true ); + if ( setsockopt( mSd, IPPROTO_TCP, TCP_NODELAY, (char *)&int_nodelay, sizeof(int_nodelay)) < 0 ) + { + Error( "setsockopt(), errno = %d, error = %s", errno, strerror(errno) ); + return( false ); + } + return( true ); } bool TcpInetServer::listen() { - return( Socket::listen() ); + return( Socket::listen() ); } bool TcpInetServer::accept() { - return( Socket::accept() ); + return( Socket::accept() ); } bool TcpInetServer::accept( TcpInetSocket *&newSocket ) { - int newSd = -1; - newSocket = 0; + int newSd = -1; + newSocket = 0; - if ( !Socket::accept( newSd ) ) - return( false ); + if ( !Socket::accept( newSd ) ) + return( false ); - newSocket = new TcpInetSocket( *this, newSd ); + newSocket = new TcpInetSocket( *this, newSd ); - return( true ); + return( true ); } bool TcpUnixServer::accept( TcpUnixSocket *&newSocket ) { - int newSd = -1; - newSocket = 0; + int newSd = -1; + newSocket = 0; - if ( !Socket::accept( newSd ) ) - return( false ); + if ( !Socket::accept( newSd ) ) + return( false ); - newSocket = new TcpUnixSocket( *this, newSd ); + newSocket = new TcpUnixSocket( *this, newSd ); - return( true ); + return( true ); } Select::Select() : mHasTimeout( false ), mMaxFd( -1 ) @@ -558,160 +558,160 @@ Select::Select() : mHasTimeout( false ), mMaxFd( -1 ) Select::Select( struct timeval timeout ) : mMaxFd( -1 ) { - setTimeout( timeout ); + setTimeout( timeout ); } Select::Select( int timeout ) : mMaxFd( -1 ) { - setTimeout( timeout ); + setTimeout( timeout ); } Select::Select( double timeout ) : mMaxFd( -1 ) { - setTimeout( timeout ); + setTimeout( timeout ); } void Select::setTimeout( int timeout ) { - mTimeout.tv_sec = timeout; - mTimeout.tv_usec = 0; - mHasTimeout = true; + mTimeout.tv_sec = timeout; + mTimeout.tv_usec = 0; + mHasTimeout = true; } void Select::setTimeout( double timeout ) { - mTimeout.tv_sec = int(timeout); - mTimeout.tv_usec = suseconds_t((timeout-mTimeout.tv_sec)*1000000.0); - mHasTimeout = true; + mTimeout.tv_sec = int(timeout); + mTimeout.tv_usec = suseconds_t((timeout-mTimeout.tv_sec)*1000000.0); + mHasTimeout = true; } void Select::setTimeout( struct timeval timeout ) { - mTimeout = timeout; - mHasTimeout = true; + mTimeout = timeout; + mHasTimeout = true; } void Select::clearTimeout() { - mHasTimeout = false; + mHasTimeout = false; } void Select::calcMaxFd() { - mMaxFd = -1; - for ( CommsSet::iterator iter = mReaders.begin(); iter != mReaders.end(); iter++ ) - if ( (*iter)->getMaxDesc() > mMaxFd ) - mMaxFd = (*iter)->getMaxDesc(); - for ( CommsSet::iterator iter = mWriters.begin(); iter != mWriters.end(); iter++ ) - if ( (*iter)->getMaxDesc() > mMaxFd ) - mMaxFd = (*iter)->getMaxDesc(); + mMaxFd = -1; + for ( CommsSet::iterator iter = mReaders.begin(); iter != mReaders.end(); iter++ ) + if ( (*iter)->getMaxDesc() > mMaxFd ) + mMaxFd = (*iter)->getMaxDesc(); + for ( CommsSet::iterator iter = mWriters.begin(); iter != mWriters.end(); iter++ ) + if ( (*iter)->getMaxDesc() > mMaxFd ) + mMaxFd = (*iter)->getMaxDesc(); } bool Select::addReader( CommsBase *comms ) { - if ( !comms->isOpen() ) - { - Error( "Unable to add closed reader" ); - return( false ); - } - std::pair result = mReaders.insert( comms ); - if ( result.second ) - if ( comms->getMaxDesc() > mMaxFd ) - mMaxFd = comms->getMaxDesc(); - return( result.second ); + if ( !comms->isOpen() ) + { + Error( "Unable to add closed reader" ); + return( false ); + } + std::pair result = mReaders.insert( comms ); + if ( result.second ) + if ( comms->getMaxDesc() > mMaxFd ) + mMaxFd = comms->getMaxDesc(); + return( result.second ); } bool Select::deleteReader( CommsBase *comms ) { - if ( !comms->isOpen() ) - { - Error( "Unable to add closed reader" ); - return( false ); - } - if ( mReaders.erase( comms ) ) - { - calcMaxFd(); - return( true ); - } + if ( !comms->isOpen() ) + { + Error( "Unable to add closed reader" ); return( false ); + } + if ( mReaders.erase( comms ) ) + { + calcMaxFd(); + return( true ); + } + return( false ); } void Select::clearReaders() { - mReaders.clear(); - mMaxFd = -1; + mReaders.clear(); + mMaxFd = -1; } bool Select::addWriter( CommsBase *comms ) { - std::pair result = mWriters.insert( comms ); - if ( result.second ) - if ( comms->getMaxDesc() > mMaxFd ) - mMaxFd = comms->getMaxDesc(); - return( result.second ); + std::pair result = mWriters.insert( comms ); + if ( result.second ) + if ( comms->getMaxDesc() > mMaxFd ) + mMaxFd = comms->getMaxDesc(); + return( result.second ); } bool Select::deleteWriter( CommsBase *comms ) { - if ( mWriters.erase( comms ) ) - { - calcMaxFd(); - return( true ); - } - return( false ); + if ( mWriters.erase( comms ) ) + { + calcMaxFd(); + return( true ); + } + return( false ); } void Select::clearWriters() { - mWriters.clear(); - mMaxFd = -1; + mWriters.clear(); + mMaxFd = -1; } int Select::wait() { - struct timeval tempTimeout = mTimeout; - struct timeval *selectTimeout = mHasTimeout?&tempTimeout:NULL; + struct timeval tempTimeout = mTimeout; + struct timeval *selectTimeout = mHasTimeout?&tempTimeout:NULL; - fd_set rfds; - fd_set wfds; + fd_set rfds; + fd_set wfds; - mReadable.clear(); - FD_ZERO(&rfds); + mReadable.clear(); + FD_ZERO(&rfds); + for ( CommsSet::iterator iter = mReaders.begin(); iter != mReaders.end(); iter++ ) + FD_SET((*iter)->getReadDesc(),&rfds); + + mWriteable.clear(); + FD_ZERO(&wfds); + for ( CommsSet::iterator iter = mWriters.begin(); iter != mWriters.end(); iter++ ) + FD_SET((*iter)->getWriteDesc(),&wfds); + + int nFound = select( mMaxFd+1, &rfds, &wfds, NULL, selectTimeout ); + if( nFound == 0 ) + { + Debug( 1, "Select timed out" ); + } + else if ( nFound < 0) + { + Error( "Select error: %s", strerror(errno) ); + } + else + { for ( CommsSet::iterator iter = mReaders.begin(); iter != mReaders.end(); iter++ ) - FD_SET((*iter)->getReadDesc(),&rfds); - - mWriteable.clear(); - FD_ZERO(&wfds); + if ( FD_ISSET((*iter)->getReadDesc(),&rfds) ) + mReadable.push_back( *iter ); for ( CommsSet::iterator iter = mWriters.begin(); iter != mWriters.end(); iter++ ) - FD_SET((*iter)->getWriteDesc(),&wfds); - - int nFound = select( mMaxFd+1, &rfds, &wfds, NULL, selectTimeout ); - if( nFound == 0 ) - { - Debug( 1, "Select timed out" ); - } - else if ( nFound < 0) - { - Error( "Select error: %s", strerror(errno) ); - } - else - { - for ( CommsSet::iterator iter = mReaders.begin(); iter != mReaders.end(); iter++ ) - if ( FD_ISSET((*iter)->getReadDesc(),&rfds) ) - mReadable.push_back( *iter ); - for ( CommsSet::iterator iter = mWriters.begin(); iter != mWriters.end(); iter++ ) - if ( FD_ISSET((*iter)->getWriteDesc(),&rfds) ) - mWriteable.push_back( *iter ); - } - return( nFound ); + if ( FD_ISSET((*iter)->getWriteDesc(),&rfds) ) + mWriteable.push_back( *iter ); + } + return( nFound ); } const Select::CommsList &Select::getReadable() const { - return( mReadable ); + return( mReadable ); } const Select::CommsList &Select::getWriteable() const { - return( mWriteable ); + return( mWriteable ); } diff --git a/src/zm_comms.h b/src/zm_comms.h index ef1dda833..d0143917c 100644 --- a/src/zm_comms.h +++ b/src/zm_comms.h @@ -40,857 +40,857 @@ class CommsException : public Exception { public: - CommsException( const std::string &message ) : Exception( message ) - { - } + CommsException( const std::string &message ) : Exception( message ) + { + } }; class CommsBase { protected: - const int &mRd; - const int &mWd; + const int &mRd; + const int &mWd; protected: - CommsBase( int &rd, int &wd ) : mRd( rd ), mWd( wd ) - { - } - virtual ~CommsBase() - { - } + CommsBase( int &rd, int &wd ) : mRd( rd ), mWd( wd ) + { + } + virtual ~CommsBase() + { + } public: - virtual bool close()=0; - virtual bool isOpen() const=0; - virtual bool isClosed() const=0; - virtual bool setBlocking( bool blocking )=0; + virtual bool close()=0; + virtual bool isOpen() const=0; + virtual bool isClosed() const=0; + virtual bool setBlocking( bool blocking )=0; public: - int getReadDesc() const - { - return( mRd ); - } - int getWriteDesc() const - { - return( mWd ); - } - int getMaxDesc() const - { - return( mRd>mWd?mRd:mWd ); - } + int getReadDesc() const + { + return( mRd ); + } + int getWriteDesc() const + { + return( mWd ); + } + int getMaxDesc() const + { + return( mRd>mWd?mRd:mWd ); + } - virtual int read( void *msg, int len ) - { - ssize_t nBytes = ::read( mRd, msg, len ); - if ( nBytes < 0 ) - Debug( 1, "Read of %d bytes max on rd %d failed: %s", len, mRd, strerror(errno) ); - return( nBytes ); - } - virtual int write( const void *msg, int len ) - { - ssize_t nBytes = ::write( mWd, msg, len ); - if ( nBytes < 0 ) - Debug( 1, "Write of %d bytes on wd %d failed: %s", len, mWd, strerror(errno) ); - return( nBytes ); - } - virtual int readV( const struct iovec *iov, int iovcnt ) - { - int nBytes = ::readv( mRd, iov, iovcnt ); - if ( nBytes < 0 ) - Debug( 1, "Readv of %d buffers max on rd %d failed: %s", iovcnt, mRd, strerror(errno) ); - return( nBytes ); - } - virtual int writeV( const struct iovec *iov, int iovcnt ) - { - ssize_t nBytes = ::writev( mWd, iov, iovcnt ); - if ( nBytes < 0 ) - Debug( 1, "Writev of %d buffers on wd %d failed: %s", iovcnt, mWd, strerror(errno) ); - return( nBytes ); - } - virtual int readV( int iovcnt, /* const void *msg1, int len1, */ ... ); - virtual int writeV( int iovcnt, /* const void *msg1, int len1, */ ... ); + virtual int read( void *msg, int len ) + { + ssize_t nBytes = ::read( mRd, msg, len ); + if ( nBytes < 0 ) + Debug( 1, "Read of %d bytes max on rd %d failed: %s", len, mRd, strerror(errno) ); + return( nBytes ); + } + virtual int write( const void *msg, int len ) + { + ssize_t nBytes = ::write( mWd, msg, len ); + if ( nBytes < 0 ) + Debug( 1, "Write of %d bytes on wd %d failed: %s", len, mWd, strerror(errno) ); + return( nBytes ); + } + virtual int readV( const struct iovec *iov, int iovcnt ) + { + int nBytes = ::readv( mRd, iov, iovcnt ); + if ( nBytes < 0 ) + Debug( 1, "Readv of %d buffers max on rd %d failed: %s", iovcnt, mRd, strerror(errno) ); + return( nBytes ); + } + virtual int writeV( const struct iovec *iov, int iovcnt ) + { + ssize_t nBytes = ::writev( mWd, iov, iovcnt ); + if ( nBytes < 0 ) + Debug( 1, "Writev of %d buffers on wd %d failed: %s", iovcnt, mWd, strerror(errno) ); + return( nBytes ); + } + virtual int readV( int iovcnt, /* const void *msg1, int len1, */ ... ); + virtual int writeV( int iovcnt, /* const void *msg1, int len1, */ ... ); }; class Pipe : public CommsBase { protected: - int mFd[2]; + int mFd[2]; public: - Pipe() : CommsBase( mFd[0], mFd[1] ) - { - mFd[0] = -1; - mFd[1] = -1; - } - ~Pipe() - { - close(); - } + Pipe() : CommsBase( mFd[0], mFd[1] ) + { + mFd[0] = -1; + mFd[1] = -1; + } + ~Pipe() + { + close(); + } public: - bool open(); - bool close(); + bool open(); + bool close(); - bool isOpen() const - { - return( mFd[0] != -1 && mFd[1] != -1 ); - } - int getReadDesc() const - { - return( mFd[0] ); - } - int getWriteDesc() const - { - return( mFd[1] ); - } + bool isOpen() const + { + return( mFd[0] != -1 && mFd[1] != -1 ); + } + int getReadDesc() const + { + return( mFd[0] ); + } + int getWriteDesc() const + { + return( mFd[1] ); + } - bool setBlocking( bool blocking ); + bool setBlocking( bool blocking ); }; class SockAddr { private: - const struct sockaddr *mAddr; + const struct sockaddr *mAddr; public: - SockAddr( const struct sockaddr *addr ); - virtual ~SockAddr() - { - } + SockAddr( const struct sockaddr *addr ); + virtual ~SockAddr() + { + } - static SockAddr *newSockAddr( const struct sockaddr &addr, socklen_t len ); - static SockAddr *newSockAddr( const SockAddr *addr ); + static SockAddr *newSockAddr( const struct sockaddr &addr, socklen_t len ); + static SockAddr *newSockAddr( const SockAddr *addr ); - int getDomain() const - { - return( mAddr?mAddr->sa_family:AF_UNSPEC ); - } + int getDomain() const + { + return( mAddr?mAddr->sa_family:AF_UNSPEC ); + } - const struct sockaddr *getAddr() const - { - return( mAddr ); - } - virtual socklen_t getAddrSize() const=0; - virtual struct sockaddr *getTempAddr() const=0; + const struct sockaddr *getAddr() const + { + return( mAddr ); + } + virtual socklen_t getAddrSize() const=0; + virtual struct sockaddr *getTempAddr() const=0; }; class SockAddrInet : public SockAddr { private: - struct sockaddr_in mAddrIn; - struct sockaddr_in mTempAddrIn; + struct sockaddr_in mAddrIn; + struct sockaddr_in mTempAddrIn; public: - SockAddrInet(); - SockAddrInet( const SockAddrInet &addr ) : SockAddr( (const struct sockaddr *)&mAddrIn ), mAddrIn( addr.mAddrIn ) - { - } - SockAddrInet( const struct sockaddr_in *addr ) : SockAddr( (const struct sockaddr *)&mAddrIn ), mAddrIn( *addr ) - { - } + SockAddrInet(); + SockAddrInet( const SockAddrInet &addr ) : SockAddr( (const struct sockaddr *)&mAddrIn ), mAddrIn( addr.mAddrIn ) + { + } + SockAddrInet( const struct sockaddr_in *addr ) : SockAddr( (const struct sockaddr *)&mAddrIn ), mAddrIn( *addr ) + { + } - bool resolve( const char *host, const char *serv, const char *proto ); - bool resolve( const char *host, int port, const char *proto ); - bool resolve( const char *serv, const char *proto ); - bool resolve( int port, const char *proto ); + bool resolve( const char *host, const char *serv, const char *proto ); + bool resolve( const char *host, int port, const char *proto ); + bool resolve( const char *serv, const char *proto ); + bool resolve( int port, const char *proto ); - socklen_t getAddrSize() const - { - return( sizeof(mAddrIn) ); - } - struct sockaddr *getTempAddr() const - { - return( (sockaddr *)&mTempAddrIn ); - } + socklen_t getAddrSize() const + { + return( sizeof(mAddrIn) ); + } + struct sockaddr *getTempAddr() const + { + return( (sockaddr *)&mTempAddrIn ); + } public: - static socklen_t addrSize() - { - return( sizeof(sockaddr_in) ); - } + static socklen_t addrSize() + { + return( sizeof(sockaddr_in) ); + } }; class SockAddrUnix : public SockAddr { private: - struct sockaddr_un mAddrUn; - struct sockaddr_un mTempAddrUn; + struct sockaddr_un mAddrUn; + struct sockaddr_un mTempAddrUn; public: - SockAddrUnix(); - SockAddrUnix( const SockAddrUnix &addr ) : SockAddr( (const struct sockaddr *)&mAddrUn ), mAddrUn( addr.mAddrUn ) - { - } - SockAddrUnix( const struct sockaddr_un *addr ) : SockAddr( (const struct sockaddr *)&mAddrUn ), mAddrUn( *addr ) - { - } + SockAddrUnix(); + SockAddrUnix( const SockAddrUnix &addr ) : SockAddr( (const struct sockaddr *)&mAddrUn ), mAddrUn( addr.mAddrUn ) + { + } + SockAddrUnix( const struct sockaddr_un *addr ) : SockAddr( (const struct sockaddr *)&mAddrUn ), mAddrUn( *addr ) + { + } - bool resolve( const char *path, const char *proto ); + bool resolve( const char *path, const char *proto ); - socklen_t getAddrSize() const - { - return( sizeof(mAddrUn) ); - } - struct sockaddr *getTempAddr() const - { - return( (sockaddr *)&mTempAddrUn ); - } + socklen_t getAddrSize() const + { + return( sizeof(mAddrUn) ); + } + struct sockaddr *getTempAddr() const + { + return( (sockaddr *)&mTempAddrUn ); + } public: - static socklen_t addrSize() - { - return( sizeof(sockaddr_un) ); - } + static socklen_t addrSize() + { + return( sizeof(sockaddr_un) ); + } }; class Socket : public CommsBase { protected: - typedef enum { CLOSED, DISCONNECTED, LISTENING, CONNECTED } State; + typedef enum { CLOSED, DISCONNECTED, LISTENING, CONNECTED } State; protected: - int mSd; - State mState; - SockAddr *mLocalAddr; - SockAddr *mRemoteAddr; + int mSd; + State mState; + SockAddr *mLocalAddr; + SockAddr *mRemoteAddr; protected: - Socket() : CommsBase( mSd, mSd ), mSd( -1 ), mState( CLOSED ), mLocalAddr( 0 ), mRemoteAddr( 0 ) - { - } - Socket( const Socket &socket, int newSd ) : CommsBase( mSd, mSd ), mSd( newSd ), mState( CONNECTED ), mLocalAddr( 0 ), mRemoteAddr( 0 ) - { - if ( socket.mLocalAddr ) - mLocalAddr = SockAddr::newSockAddr( mLocalAddr ); - if ( socket.mRemoteAddr ) - mRemoteAddr = SockAddr::newSockAddr( mRemoteAddr ); - } - virtual ~Socket() - { - close(); - delete mLocalAddr; - delete mRemoteAddr; - } + Socket() : CommsBase( mSd, mSd ), mSd( -1 ), mState( CLOSED ), mLocalAddr( 0 ), mRemoteAddr( 0 ) + { + } + Socket( const Socket &socket, int newSd ) : CommsBase( mSd, mSd ), mSd( newSd ), mState( CONNECTED ), mLocalAddr( 0 ), mRemoteAddr( 0 ) + { + if ( socket.mLocalAddr ) + mLocalAddr = SockAddr::newSockAddr( mLocalAddr ); + if ( socket.mRemoteAddr ) + mRemoteAddr = SockAddr::newSockAddr( mRemoteAddr ); + } + virtual ~Socket() + { + close(); + delete mLocalAddr; + delete mRemoteAddr; + } public: - bool isOpen() const - { - return( !isClosed() ); - } - bool isClosed() const - { - return( mState == CLOSED ); - } - bool isDisconnected() const - { - return( mState == DISCONNECTED ); - } - bool isConnected() const - { - return( mState == CONNECTED ); - } - virtual bool close(); + bool isOpen() const + { + return( !isClosed() ); + } + bool isClosed() const + { + return( mState == CLOSED ); + } + bool isDisconnected() const + { + return( mState == DISCONNECTED ); + } + bool isConnected() const + { + return( mState == CONNECTED ); + } + virtual bool close(); protected: - bool isListening() const - { - return( mState == LISTENING ); - } + bool isListening() const + { + return( mState == LISTENING ); + } protected: - virtual bool socket(); - virtual bool bind(); + virtual bool socket(); + virtual bool bind(); protected: - virtual bool connect(); - virtual bool listen(); - virtual bool accept(); - virtual bool accept( int & ); + virtual bool connect(); + virtual bool listen(); + virtual bool accept(); + virtual bool accept( int & ); public: - virtual int send( const void *msg, int len ) const - { - ssize_t nBytes = ::send( mSd, msg, len, 0 ); - if ( nBytes < 0 ) - Debug( 1, "Send of %d bytes on sd %d failed: %s", len, mSd, strerror(errno) ); - return( nBytes ); - } - virtual int recv( void *msg, int len ) const - { - ssize_t nBytes = ::recv( mSd, msg, len, 0 ); - if ( nBytes < 0 ) - Debug( 1, "Recv of %d bytes max on sd %d failed: %s", len, mSd, strerror(errno) ); - return( nBytes ); - } - virtual int send( const std::string &msg ) const - { - ssize_t nBytes = ::send( mSd, msg.data(), msg.size(), 0 ); - if ( nBytes < 0 ) - Debug( 1, "Send of string '%s' (%zd bytes) on sd %d failed: %s", msg.c_str(), msg.size(), mSd, strerror(errno) ); - return( nBytes ); - } - virtual int recv( std::string &msg ) const - { - char buffer[msg.capacity()]; - int nBytes = 0; - if ( (nBytes = ::recv( mSd, buffer, sizeof(buffer), 0 )) < 0 ) - { - Debug( 1, "Recv of %zd bytes max to string on sd %d failed: %s", sizeof(buffer), mSd, strerror(errno) ); - return( nBytes ); - } - buffer[nBytes] = '\0'; - msg = buffer; - return( nBytes ); - } - virtual int recv( std::string &msg, size_t maxLen ) const - { - char buffer[maxLen]; - int nBytes = 0; - if ( (nBytes = ::recv( mSd, buffer, sizeof(buffer), 0 )) < 0 ) - { - Debug( 1, "Recv of %zd bytes max to string on sd %d failed: %s", maxLen, mSd, strerror(errno) ); - return( nBytes ); - } - buffer[nBytes] = '\0'; - msg = buffer; - return( nBytes ); - } - virtual int bytesToRead() const; - - int getDesc() const - { - return( mSd ); - } - //virtual bool isOpen() const - //{ - //return( mSd != -1 ); - //} - - virtual int getDomain() const=0; - virtual int getType() const=0; - virtual const char *getProtocol() const=0; - - const SockAddr *getLocalAddr() const + virtual int send( const void *msg, int len ) const + { + ssize_t nBytes = ::send( mSd, msg, len, 0 ); + if ( nBytes < 0 ) + Debug( 1, "Send of %d bytes on sd %d failed: %s", len, mSd, strerror(errno) ); + return( nBytes ); + } + virtual int recv( void *msg, int len ) const + { + ssize_t nBytes = ::recv( mSd, msg, len, 0 ); + if ( nBytes < 0 ) + Debug( 1, "Recv of %d bytes max on sd %d failed: %s", len, mSd, strerror(errno) ); + return( nBytes ); + } + virtual int send( const std::string &msg ) const + { + ssize_t nBytes = ::send( mSd, msg.data(), msg.size(), 0 ); + if ( nBytes < 0 ) + Debug( 1, "Send of string '%s' (%zd bytes) on sd %d failed: %s", msg.c_str(), msg.size(), mSd, strerror(errno) ); + return( nBytes ); + } + virtual int recv( std::string &msg ) const + { + char buffer[msg.capacity()]; + int nBytes = 0; + if ( (nBytes = ::recv( mSd, buffer, sizeof(buffer), 0 )) < 0 ) { - return( mLocalAddr ); + Debug( 1, "Recv of %zd bytes max to string on sd %d failed: %s", sizeof(buffer), mSd, strerror(errno) ); + return( nBytes ); } - const SockAddr *getRemoteAddr() const + buffer[nBytes] = '\0'; + msg = buffer; + return( nBytes ); + } + virtual int recv( std::string &msg, size_t maxLen ) const + { + char buffer[maxLen]; + int nBytes = 0; + if ( (nBytes = ::recv( mSd, buffer, sizeof(buffer), 0 )) < 0 ) { - return( mRemoteAddr ); + Debug( 1, "Recv of %zd bytes max to string on sd %d failed: %s", maxLen, mSd, strerror(errno) ); + return( nBytes ); } - virtual socklen_t getAddrSize() const=0; + buffer[nBytes] = '\0'; + msg = buffer; + return( nBytes ); + } + virtual int bytesToRead() const; - bool getBlocking( bool &blocking ); - bool setBlocking( bool blocking ); + int getDesc() const + { + return( mSd ); + } + //virtual bool isOpen() const + //{ + //return( mSd != -1 ); + //} - bool getSendBufferSize( int & ) const; - bool getRecvBufferSize( int & ) const; + virtual int getDomain() const=0; + virtual int getType() const=0; + virtual const char *getProtocol() const=0; - bool setSendBufferSize( int ); - bool setRecvBufferSize( int ); + const SockAddr *getLocalAddr() const + { + return( mLocalAddr ); + } + const SockAddr *getRemoteAddr() const + { + return( mRemoteAddr ); + } + virtual socklen_t getAddrSize() const=0; - bool getRouting( bool & ) const; - bool setRouting( bool ); + bool getBlocking( bool &blocking ); + bool setBlocking( bool blocking ); - bool getNoDelay( bool & ) const; - bool setNoDelay( bool ); + bool getSendBufferSize( int & ) const; + bool getRecvBufferSize( int & ) const; + + bool setSendBufferSize( int ); + bool setRecvBufferSize( int ); + + bool getRouting( bool & ) const; + bool setRouting( bool ); + + bool getNoDelay( bool & ) const; + bool setNoDelay( bool ); }; class InetSocket : virtual public Socket { public: - int getDomain() const - { - return( AF_INET ); - } - virtual socklen_t getAddrSize() const - { - return( SockAddrInet::addrSize() ); - } + int getDomain() const + { + return( AF_INET ); + } + virtual socklen_t getAddrSize() const + { + return( SockAddrInet::addrSize() ); + } protected: - bool resolveLocal( const char *host, const char *serv, const char *proto ) - { - SockAddrInet *addr = new SockAddrInet; - mLocalAddr = addr; - return( addr->resolve( host, serv, proto ) ); - } - bool resolveLocal( const char *host, int port, const char *proto ) - { - SockAddrInet *addr = new SockAddrInet; - mLocalAddr = addr; - return( addr->resolve( host, port, proto ) ); - } - bool resolveLocal( const char *serv, const char *proto ) - { - SockAddrInet *addr = new SockAddrInet; - mLocalAddr = addr; - return( addr->resolve( serv, proto ) ); - } - bool resolveLocal( int port, const char *proto ) - { - SockAddrInet *addr = new SockAddrInet; - mLocalAddr = addr; - return( addr->resolve( port, proto ) ); - } + bool resolveLocal( const char *host, const char *serv, const char *proto ) + { + SockAddrInet *addr = new SockAddrInet; + mLocalAddr = addr; + return( addr->resolve( host, serv, proto ) ); + } + bool resolveLocal( const char *host, int port, const char *proto ) + { + SockAddrInet *addr = new SockAddrInet; + mLocalAddr = addr; + return( addr->resolve( host, port, proto ) ); + } + bool resolveLocal( const char *serv, const char *proto ) + { + SockAddrInet *addr = new SockAddrInet; + mLocalAddr = addr; + return( addr->resolve( serv, proto ) ); + } + bool resolveLocal( int port, const char *proto ) + { + SockAddrInet *addr = new SockAddrInet; + mLocalAddr = addr; + return( addr->resolve( port, proto ) ); + } - bool resolveRemote( const char *host, const char *serv, const char *proto ) - { - SockAddrInet *addr = new SockAddrInet; - mRemoteAddr = addr; - return( addr->resolve( host, serv, proto ) ); - } - bool resolveRemote( const char *host, int port, const char *proto ) - { - SockAddrInet *addr = new SockAddrInet; - mRemoteAddr = addr; - return( addr->resolve( host, port, proto ) ); - } + bool resolveRemote( const char *host, const char *serv, const char *proto ) + { + SockAddrInet *addr = new SockAddrInet; + mRemoteAddr = addr; + return( addr->resolve( host, serv, proto ) ); + } + bool resolveRemote( const char *host, int port, const char *proto ) + { + SockAddrInet *addr = new SockAddrInet; + mRemoteAddr = addr; + return( addr->resolve( host, port, proto ) ); + } protected: - bool bind( const SockAddrInet &addr ) - { - mLocalAddr = new SockAddrInet( addr ); - return( Socket::bind() ); - } - bool bind( const char *host, const char *serv ) - { - if ( !resolveLocal( host, serv, getProtocol() ) ) - return( false ); - return( Socket::bind() ); - } - bool bind( const char *host, int port ) - { - if ( !resolveLocal( host, port, getProtocol() ) ) - return( false ); - return( Socket::bind() ); - } - bool bind( const char *serv ) - { - if ( !resolveLocal( serv, getProtocol() ) ) - return( false ); - return( Socket::bind() ); - } - bool bind( int port ) - { - if ( !resolveLocal( port, getProtocol() ) ) - return( false ); - return( Socket::bind() ); - } + bool bind( const SockAddrInet &addr ) + { + mLocalAddr = new SockAddrInet( addr ); + return( Socket::bind() ); + } + bool bind( const char *host, const char *serv ) + { + if ( !resolveLocal( host, serv, getProtocol() ) ) + return( false ); + return( Socket::bind() ); + } + bool bind( const char *host, int port ) + { + if ( !resolveLocal( host, port, getProtocol() ) ) + return( false ); + return( Socket::bind() ); + } + bool bind( const char *serv ) + { + if ( !resolveLocal( serv, getProtocol() ) ) + return( false ); + return( Socket::bind() ); + } + bool bind( int port ) + { + if ( !resolveLocal( port, getProtocol() ) ) + return( false ); + return( Socket::bind() ); + } - bool connect( const SockAddrInet &addr ) - { - mRemoteAddr = new SockAddrInet( addr ); - return( Socket::connect() ); - } - bool connect( const char *host, const char *serv ) - { - if ( !resolveRemote( host, serv, getProtocol() ) ) - return( false ); - return( Socket::connect() ); - } - bool connect( const char *host, int port ) - { - if ( !resolveRemote( host, port, getProtocol() ) ) - return( false ); - return( Socket::connect() ); - } + bool connect( const SockAddrInet &addr ) + { + mRemoteAddr = new SockAddrInet( addr ); + return( Socket::connect() ); + } + bool connect( const char *host, const char *serv ) + { + if ( !resolveRemote( host, serv, getProtocol() ) ) + return( false ); + return( Socket::connect() ); + } + bool connect( const char *host, int port ) + { + if ( !resolveRemote( host, port, getProtocol() ) ) + return( false ); + return( Socket::connect() ); + } }; class UnixSocket : virtual public Socket { public: - int getDomain() const - { - return( AF_UNIX ); - } - virtual socklen_t getAddrSize() const - { - return( SockAddrUnix::addrSize() ); - } + int getDomain() const + { + return( AF_UNIX ); + } + virtual socklen_t getAddrSize() const + { + return( SockAddrUnix::addrSize() ); + } protected: - bool resolveLocal( const char *serv, const char *proto ) - { - SockAddrUnix *addr = new SockAddrUnix; - mLocalAddr = addr; - return( addr->resolve( serv, proto ) ); - } + bool resolveLocal( const char *serv, const char *proto ) + { + SockAddrUnix *addr = new SockAddrUnix; + mLocalAddr = addr; + return( addr->resolve( serv, proto ) ); + } - bool resolveRemote( const char *path, const char *proto ) - { - SockAddrUnix *addr = new SockAddrUnix; - mRemoteAddr = addr; - return( addr->resolve( path, proto ) ); - } + bool resolveRemote( const char *path, const char *proto ) + { + SockAddrUnix *addr = new SockAddrUnix; + mRemoteAddr = addr; + return( addr->resolve( path, proto ) ); + } protected: - bool bind( const char *path ) - { - if ( !UnixSocket::resolveLocal( path, getProtocol() ) ) - return( false ); - return( Socket::bind() ); - } + bool bind( const char *path ) + { + if ( !UnixSocket::resolveLocal( path, getProtocol() ) ) + return( false ); + return( Socket::bind() ); + } - bool connect( const char *path ) - { - if ( !UnixSocket::resolveRemote( path, getProtocol() ) ) - return( false ); - return( Socket::connect() ); - } + bool connect( const char *path ) + { + if ( !UnixSocket::resolveRemote( path, getProtocol() ) ) + return( false ); + return( Socket::connect() ); + } }; class UdpSocket : virtual public Socket { public: - int getType() const - { - return( SOCK_DGRAM ); - } - const char *getProtocol() const - { - return( "udp" ); - } + int getType() const + { + return( SOCK_DGRAM ); + } + const char *getProtocol() const + { + return( "udp" ); + } public: - virtual int sendto( const void *msg, int len, const SockAddr *addr=0 ) const - { - ssize_t nBytes = ::sendto( mSd, msg, len, 0, addr?addr->getAddr():NULL, addr?addr->getAddrSize():0 ); - if ( nBytes < 0 ) - Debug( 1, "Sendto of %d bytes on sd %d failed: %s", len, mSd, strerror(errno) ); - return( nBytes ); - } - virtual int recvfrom( void *msg, int len, SockAddr *addr=0 ) const - { - ssize_t nBytes = 0; - if ( addr ) - { - struct sockaddr sockAddr; - socklen_t sockLen; - nBytes = ::recvfrom( mSd, msg, len, 0, &sockAddr, &sockLen ); - if ( nBytes < 0 ) - { - Debug( 1, "Recvfrom of %d bytes max on sd %d (with address) failed: %s", len, mSd, strerror(errno) ); - } - else if ( sockLen ) - { - addr = SockAddr::newSockAddr( sockAddr, sockLen ); - } - } - else - { - nBytes = ::recvfrom( mSd, msg, len, 0, NULL, 0 ); - if ( nBytes < 0 ) - Debug( 1, "Recvfrom of %d bytes max on sd %d (no address) failed: %s", len, mSd, strerror(errno) ); - } - return( nBytes ); - } + virtual int sendto( const void *msg, int len, const SockAddr *addr=0 ) const + { + ssize_t nBytes = ::sendto( mSd, msg, len, 0, addr?addr->getAddr():NULL, addr?addr->getAddrSize():0 ); + if ( nBytes < 0 ) + Debug( 1, "Sendto of %d bytes on sd %d failed: %s", len, mSd, strerror(errno) ); + return( nBytes ); + } + virtual int recvfrom( void *msg, int len, SockAddr *addr=0 ) const + { + ssize_t nBytes = 0; + if ( addr ) + { + struct sockaddr sockAddr; + socklen_t sockLen; + nBytes = ::recvfrom( mSd, msg, len, 0, &sockAddr, &sockLen ); + if ( nBytes < 0 ) + { + Debug( 1, "Recvfrom of %d bytes max on sd %d (with address) failed: %s", len, mSd, strerror(errno) ); + } + else if ( sockLen ) + { + addr = SockAddr::newSockAddr( sockAddr, sockLen ); + } + } + else + { + nBytes = ::recvfrom( mSd, msg, len, 0, NULL, 0 ); + if ( nBytes < 0 ) + Debug( 1, "Recvfrom of %d bytes max on sd %d (no address) failed: %s", len, mSd, strerror(errno) ); + } + return( nBytes ); + } }; class UdpInetSocket : virtual public UdpSocket, virtual public InetSocket { public: - bool bind( const SockAddrInet &addr ) - { - return( InetSocket::bind( addr ) ); - } - bool bind( const char *host, const char *serv ) - { - return( InetSocket::bind( host, serv ) ); - } - bool bind( const char *host, int port ) - { - return( InetSocket::bind( host, port ) ); - } - bool bind( const char *serv ) - { - return( InetSocket::bind( serv ) ); - } - bool bind( int port ) - { - return( InetSocket::bind( port ) ); - } + bool bind( const SockAddrInet &addr ) + { + return( InetSocket::bind( addr ) ); + } + bool bind( const char *host, const char *serv ) + { + return( InetSocket::bind( host, serv ) ); + } + bool bind( const char *host, int port ) + { + return( InetSocket::bind( host, port ) ); + } + bool bind( const char *serv ) + { + return( InetSocket::bind( serv ) ); + } + bool bind( int port ) + { + return( InetSocket::bind( port ) ); + } - bool connect( const SockAddrInet &addr ) - { - return( InetSocket::connect( addr ) ); - } - bool connect( const char *host, const char *serv ) - { - return( InetSocket::connect( host, serv ) ); - } - bool connect( const char *host, int port ) - { - return( InetSocket::connect( host, port ) ); - } + bool connect( const SockAddrInet &addr ) + { + return( InetSocket::connect( addr ) ); + } + bool connect( const char *host, const char *serv ) + { + return( InetSocket::connect( host, serv ) ); + } + bool connect( const char *host, int port ) + { + return( InetSocket::connect( host, port ) ); + } }; class UdpUnixSocket : virtual public UdpSocket, virtual public UnixSocket { public: - bool bind( const char *path ) - { - return( UnixSocket::bind( path ) ); - } + bool bind( const char *path ) + { + return( UnixSocket::bind( path ) ); + } - bool connect( const char *path ) - { - return( UnixSocket::connect( path ) ); - } + bool connect( const char *path ) + { + return( UnixSocket::connect( path ) ); + } }; class UdpInetClient : public UdpInetSocket { protected: - bool bind( const SockAddrInet &addr ) - { - return( UdpInetSocket::bind( addr ) ); - } - bool bind( const char *host, const char *serv ) - { - return( UdpInetSocket::bind( host, serv ) ); - } - bool bind( const char *host, int port ) - { - return( UdpInetSocket::bind( host, port ) ); - } - bool bind( const char *serv ) - { - return( UdpInetSocket::bind( serv ) ); - } - bool bind( int port ) - { - return( UdpInetSocket::bind( port ) ); - } + bool bind( const SockAddrInet &addr ) + { + return( UdpInetSocket::bind( addr ) ); + } + bool bind( const char *host, const char *serv ) + { + return( UdpInetSocket::bind( host, serv ) ); + } + bool bind( const char *host, int port ) + { + return( UdpInetSocket::bind( host, port ) ); + } + bool bind( const char *serv ) + { + return( UdpInetSocket::bind( serv ) ); + } + bool bind( int port ) + { + return( UdpInetSocket::bind( port ) ); + } public: - bool connect( const SockAddrInet &addr ) - { - return( UdpInetSocket::connect( addr ) ); - } - bool connect( const char *host, const char *serv ) - { - return( UdpInetSocket::connect( host, serv ) ); - } - bool connect( const char *host, int port ) - { - return( UdpInetSocket::connect( host, port ) ); - } + bool connect( const SockAddrInet &addr ) + { + return( UdpInetSocket::connect( addr ) ); + } + bool connect( const char *host, const char *serv ) + { + return( UdpInetSocket::connect( host, serv ) ); + } + bool connect( const char *host, int port ) + { + return( UdpInetSocket::connect( host, port ) ); + } }; class UdpUnixClient : public UdpUnixSocket { public: - bool bind( const char *path ) - { - return( UdpUnixSocket::bind( path ) ); - } + bool bind( const char *path ) + { + return( UdpUnixSocket::bind( path ) ); + } public: - bool connect( const char *path ) - { - return( UdpUnixSocket::connect( path) ); - } + bool connect( const char *path ) + { + return( UdpUnixSocket::connect( path) ); + } }; class UdpInetServer : public UdpInetSocket { public: - bool bind( const SockAddrInet &addr ) - { - return( UdpInetSocket::bind( addr ) ); - } - bool bind( const char *host, const char *serv ) - { - return( UdpInetSocket::bind( host, serv ) ); - } - bool bind( const char *host, int port ) - { - return( UdpInetSocket::bind( host, port ) ); - } - bool bind( const char *serv ) - { - return( UdpInetSocket::bind( serv ) ); - } - bool bind( int port ) - { - return( UdpInetSocket::bind( port ) ); - } + bool bind( const SockAddrInet &addr ) + { + return( UdpInetSocket::bind( addr ) ); + } + bool bind( const char *host, const char *serv ) + { + return( UdpInetSocket::bind( host, serv ) ); + } + bool bind( const char *host, int port ) + { + return( UdpInetSocket::bind( host, port ) ); + } + bool bind( const char *serv ) + { + return( UdpInetSocket::bind( serv ) ); + } + bool bind( int port ) + { + return( UdpInetSocket::bind( port ) ); + } protected: - bool connect( const char *host, const char *serv ) - { - return( UdpInetSocket::connect( host, serv ) ); - } - bool connect( const char *host, int port ) - { - return( UdpInetSocket::connect( host, port ) ); - } + bool connect( const char *host, const char *serv ) + { + return( UdpInetSocket::connect( host, serv ) ); + } + bool connect( const char *host, int port ) + { + return( UdpInetSocket::connect( host, port ) ); + } }; class UdpUnixServer : public UdpUnixSocket { public: - bool bind( const char *path ) - { - return( UdpUnixSocket::bind( path ) ); - } + bool bind( const char *path ) + { + return( UdpUnixSocket::bind( path ) ); + } protected: - bool connect( const char *path ) - { - return( UdpUnixSocket::connect( path ) ); - } + bool connect( const char *path ) + { + return( UdpUnixSocket::connect( path ) ); + } }; class TcpSocket : virtual public Socket { public: - TcpSocket() - { - } - TcpSocket( const TcpSocket &socket, int newSd ) : Socket( socket, newSd ) - { - } + TcpSocket() + { + } + TcpSocket( const TcpSocket &socket, int newSd ) : Socket( socket, newSd ) + { + } public: - int getType() const - { - return( SOCK_STREAM ); - } - const char *getProtocol() const - { - return( "tcp" ); - } + int getType() const + { + return( SOCK_STREAM ); + } + const char *getProtocol() const + { + return( "tcp" ); + } }; class TcpInetSocket : virtual public TcpSocket, virtual public InetSocket { public: - TcpInetSocket() - { - } - TcpInetSocket( const TcpInetSocket &socket, int newSd ) : TcpSocket( socket, newSd ) - { - } + TcpInetSocket() + { + } + TcpInetSocket( const TcpInetSocket &socket, int newSd ) : TcpSocket( socket, newSd ) + { + } }; class TcpUnixSocket : virtual public TcpSocket, virtual public UnixSocket { public: - TcpUnixSocket() - { - } - TcpUnixSocket( const TcpUnixSocket &socket, int newSd ) : TcpSocket( socket, newSd ) - { - } + TcpUnixSocket() + { + } + TcpUnixSocket( const TcpUnixSocket &socket, int newSd ) : TcpSocket( socket, newSd ) + { + } }; class TcpInetClient : public TcpInetSocket { public: - bool connect( const char *host, const char *serv ) - { - return( TcpInetSocket::connect( host, serv ) ); - } - bool connect( const char *host, int port ) - { - return( TcpInetSocket::connect( host, port ) ); - } + bool connect( const char *host, const char *serv ) + { + return( TcpInetSocket::connect( host, serv ) ); + } + bool connect( const char *host, int port ) + { + return( TcpInetSocket::connect( host, port ) ); + } }; class TcpUnixClient : public TcpUnixSocket { public: - bool connect( const char *path ) - { - return( TcpUnixSocket::connect( path) ); - } + bool connect( const char *path ) + { + return( TcpUnixSocket::connect( path) ); + } }; class TcpInetServer : public TcpInetSocket { public: - bool bind( const char *host, const char *serv ) - { - return( TcpInetSocket::bind( host, serv ) ); - } - bool bind( const char *host, int port ) - { - return( TcpInetSocket::bind( host, port ) ); - } - bool bind( const char *serv ) - { - return( TcpInetSocket::bind( serv ) ); - } - bool bind( int port ) - { - return( TcpInetSocket::bind( port ) ); - } + bool bind( const char *host, const char *serv ) + { + return( TcpInetSocket::bind( host, serv ) ); + } + bool bind( const char *host, int port ) + { + return( TcpInetSocket::bind( host, port ) ); + } + bool bind( const char *serv ) + { + return( TcpInetSocket::bind( serv ) ); + } + bool bind( int port ) + { + return( TcpInetSocket::bind( port ) ); + } public: - bool isListening() const { return( Socket::isListening() ); } - bool listen(); - bool accept(); - bool accept( TcpInetSocket *&newSocket ); + bool isListening() const { return( Socket::isListening() ); } + bool listen(); + bool accept(); + bool accept( TcpInetSocket *&newSocket ); }; class TcpUnixServer : public TcpUnixSocket { public: - bool bind( const char *path ) - { - return( TcpUnixSocket::bind( path ) ); - } + bool bind( const char *path ) + { + return( TcpUnixSocket::bind( path ) ); + } public: - bool isListening() const { return( Socket::isListening() ); } - bool listen(); - bool accept(); - bool accept( TcpUnixSocket *&newSocket ); + bool isListening() const { return( Socket::isListening() ); } + bool listen(); + bool accept(); + bool accept( TcpUnixSocket *&newSocket ); }; class Select { public: - typedef std::set CommsSet; - typedef std::vector CommsList; + typedef std::set CommsSet; + typedef std::vector CommsList; protected: - CommsSet mReaders; - CommsSet mWriters; - CommsList mReadable; - CommsList mWriteable; - bool mHasTimeout; - struct timeval mTimeout; - int mMaxFd; + CommsSet mReaders; + CommsSet mWriters; + CommsList mReadable; + CommsList mWriteable; + bool mHasTimeout; + struct timeval mTimeout; + int mMaxFd; public: - Select(); - Select( struct timeval timeout ); - Select( int timeout ); - Select( double timeout ); + Select(); + Select( struct timeval timeout ); + Select( int timeout ); + Select( double timeout ); - void setTimeout( int timeout ); - void setTimeout( double timeout ); - void setTimeout( struct timeval timeout ); - void clearTimeout(); + void setTimeout( int timeout ); + void setTimeout( double timeout ); + void setTimeout( struct timeval timeout ); + void clearTimeout(); - void calcMaxFd(); + void calcMaxFd(); - bool addReader( CommsBase *comms ); - bool deleteReader( CommsBase *comms ); - void clearReaders(); + bool addReader( CommsBase *comms ); + bool deleteReader( CommsBase *comms ); + void clearReaders(); - bool addWriter( CommsBase *comms ); - bool deleteWriter( CommsBase *comms ); - void clearWriters(); + bool addWriter( CommsBase *comms ); + bool deleteWriter( CommsBase *comms ); + void clearWriters(); - int wait(); + int wait(); - const CommsList &getReadable() const; - const CommsList &getWriteable() const; + const CommsList &getReadable() const; + const CommsList &getWriteable() const; }; #endif // ZM_COMMS_H diff --git a/src/zm_config.cpp b/src/zm_config.cpp index 5a7454a7b..1a5c65840 100644 --- a/src/zm_config.cpp +++ b/src/zm_config.cpp @@ -117,7 +117,8 @@ void zmLoadConfig() Debug( 1, "Fetching ZM_SERVER_ID For Name = %s", staticConfig.SERVER_NAME.c_str() ); std::string sql = stringtf("SELECT Id FROM Servers WHERE Name='%s'", staticConfig.SERVER_NAME.c_str() ); - if ( MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ) ) { + zmDbRow dbrow; + if ( dbrow.fetch( sql.c_str() ) ) { staticConfig.SERVER_ID = atoi(dbrow[0]); } else { Fatal("Can't get ServerId for Server %s", staticConfig.SERVER_NAME.c_str() ); @@ -128,7 +129,8 @@ void zmLoadConfig() Debug( 1, "Fetching ZM_SERVER_NAME For Id = %d", staticConfig.SERVER_ID ); std::string sql = stringtf("SELECT Name FROM Servers WHERE Id='%d'", staticConfig.SERVER_ID ); - if ( MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ) ) { + zmDbRow dbrow; + if ( dbrow.fetch( sql.c_str() ) ) { staticConfig.SERVER_NAME = std::string(dbrow[0]); } else { Fatal("Can't get ServerName for Server ID %d", staticConfig.SERVER_ID ); diff --git a/src/zm_config.h.in b/src/zm_config.h.in index 83aa19210..1deeff861 100644 --- a/src/zm_config.h.in +++ b/src/zm_config.h.in @@ -25,48 +25,48 @@ #include -#define ZM_CONFIG "@ZM_CONFIG@" // Path to config file -#define ZM_VERSION "@VERSION@" // ZoneMinder Version +#define ZM_CONFIG "@ZM_CONFIG@" // Path to config file +#define ZM_VERSION "@VERSION@" // ZoneMinder Version -#define ZM_HAS_V4L1 @ZM_HAS_V4L1@ -#define ZM_HAS_V4L2 @ZM_HAS_V4L2@ -#define ZM_HAS_V4L @ZM_HAS_V4L@ +#define ZM_HAS_V4L1 @ZM_HAS_V4L1@ +#define ZM_HAS_V4L2 @ZM_HAS_V4L2@ +#define ZM_HAS_V4L @ZM_HAS_V4L@ #ifdef HAVE_LIBAVFORMAT -#define ZM_HAS_FFMPEG 1 +#define ZM_HAS_FFMPEG 1 #endif // HAVE_LIBAVFORMAT -#define ZM_MAX_IMAGE_WIDTH 2048 // The largest image we imagine ever handling -#define ZM_MAX_IMAGE_HEIGHT 1536 // The largest image we imagine ever handling -#define ZM_MAX_IMAGE_COLOURS 4 // The largest image we imagine ever handling -#define ZM_MAX_IMAGE_DIM (ZM_MAX_IMAGE_WIDTH*ZM_MAX_IMAGE_HEIGHT) -#define ZM_MAX_IMAGE_SIZE (ZM_MAX_IMAGE_DIM*ZM_MAX_IMAGE_COLOURS) +#define ZM_MAX_IMAGE_WIDTH 2048 // The largest image we imagine ever handling +#define ZM_MAX_IMAGE_HEIGHT 1536 // The largest image we imagine ever handling +#define ZM_MAX_IMAGE_COLOURS 4 // The largest image we imagine ever handling +#define ZM_MAX_IMAGE_DIM (ZM_MAX_IMAGE_WIDTH*ZM_MAX_IMAGE_HEIGHT) +#define ZM_MAX_IMAGE_SIZE (ZM_MAX_IMAGE_DIM*ZM_MAX_IMAGE_COLOURS) -#define ZM_SCALE_BASE 100 // The factor by which we bump up 'scale' to simulate FP -#define ZM_RATE_BASE 100 // The factor by which we bump up 'rate' to simulate FP +#define ZM_SCALE_BASE 100 // The factor by which we bump up 'scale' to simulate FP +#define ZM_RATE_BASE 100 // The factor by which we bump up 'rate' to simulate FP -#define ZM_SQL_BATCH_SIZE 50 // Limit the size of multi-row SQL statements -#define ZM_SQL_SML_BUFSIZ 256 // Size of SQL buffer -#define ZM_SQL_MED_BUFSIZ 1024 // Size of SQL buffer -#define ZM_SQL_LGE_BUFSIZ 8192 // Size of SQL buffer +#define ZM_SQL_BATCH_SIZE 50 // Limit the size of multi-row SQL statements +#define ZM_SQL_SML_BUFSIZ 256 // Size of SQL buffer +#define ZM_SQL_MED_BUFSIZ 1024 // Size of SQL buffer +#define ZM_SQL_LGE_BUFSIZ 8192 // Size of SQL buffer -#define ZM_NETWORK_BUFSIZ 32768 // Size of network buffer +#define ZM_NETWORK_BUFSIZ 32768 // Size of network buffer -#define ZM_MAX_FPS 30 // The maximum frame rate we expect to handle -#define ZM_SAMPLE_RATE int(1000000/ZM_MAX_FPS) // A general nyquist sample frequency for delays etc -#define ZM_SUSPENDED_RATE int(1000000/4) // A slower rate for when disabled etc +#define ZM_MAX_FPS 30 // The maximum frame rate we expect to handle +#define ZM_SAMPLE_RATE int(1000000/ZM_MAX_FPS) // A general nyquist sample frequency for delays etc +#define ZM_SUSPENDED_RATE int(1000000/4) // A slower rate for when disabled etc extern void zmLoadConfig(); struct StaticConfig { - std::string DB_HOST; - std::string DB_NAME; - std::string DB_USER; - std::string DB_PASS; - std::string PATH_WEB; - std::string SERVER_NAME; - unsigned int SERVER_ID; + std::string DB_HOST; + std::string DB_NAME; + std::string DB_USER; + std::string DB_PASS; + std::string PATH_WEB; + std::string SERVER_NAME; + unsigned int SERVER_ID; }; extern StaticConfig staticConfig; @@ -74,63 +74,63 @@ extern StaticConfig staticConfig; class ConfigItem { private: - char *name; - char *value; - char *type; + char *name; + char *value; + char *type; - mutable enum { CFG_BOOLEAN, CFG_INTEGER, CFG_DECIMAL, CFG_STRING } cfg_type; - mutable union - { - bool boolean_value; - int integer_value; - double decimal_value; - char *string_value; - } cfg_value; - mutable bool accessed; + mutable enum { CFG_BOOLEAN, CFG_INTEGER, CFG_DECIMAL, CFG_STRING } cfg_type; + mutable union + { + bool boolean_value; + int integer_value; + double decimal_value; + char *string_value; + } cfg_value; + mutable bool accessed; public: - ConfigItem( const char *p_name, const char *p_value, const char *const p_type ); - ~ConfigItem(); - void ConvertValue() const; - bool BooleanValue() const; - int IntegerValue() const; - double DecimalValue() const; - const char *StringValue() const; + ConfigItem( const char *p_name, const char *p_value, const char *const p_type ); + ~ConfigItem(); + void ConvertValue() const; + bool BooleanValue() const; + int IntegerValue() const; + double DecimalValue() const; + const char *StringValue() const; - inline operator bool() const - { - return( BooleanValue() ); - } - inline operator int() const - { - return( IntegerValue() ); - } - inline operator double() const - { - return( DecimalValue() ); - } - inline operator const char *() const - { - return( StringValue() ); - } + inline operator bool() const + { + return( BooleanValue() ); + } + inline operator int() const + { + return( IntegerValue() ); + } + inline operator double() const + { + return( DecimalValue() ); + } + inline operator const char *() const + { + return( StringValue() ); + } }; class Config { public: - ZM_CFG_DECLARE_LIST + ZM_CFG_DECLARE_LIST private: - int n_items; - ConfigItem **items; + int n_items; + ConfigItem **items; public: - Config(); - ~Config(); + Config(); + ~Config(); - void Load(); - void Assign(); - const ConfigItem &Item( int id ); + void Load(); + void Assign(); + const ConfigItem &Item( int id ); }; extern Config config; diff --git a/src/zm_coord.h b/src/zm_coord.h index 6a6620529..7316244a2 100644 --- a/src/zm_coord.h +++ b/src/zm_coord.h @@ -28,40 +28,40 @@ class Coord { private: - int x, y; + int x, y; public: - inline Coord() : x(0), y(0) - { - } - inline Coord( int p_x, int p_y ) : x(p_x), y(p_y) - { - } - inline Coord( const Coord &p_coord ) : x(p_coord.x), y(p_coord.y) - { - } - inline int &X() { return( x ); } - inline const int &X() const { return( x ); } - inline int &Y() { return( y ); } - inline const int &Y() const { return( y ); } + inline Coord() : x(0), y(0) + { + } + inline Coord( int p_x, int p_y ) : x(p_x), y(p_y) + { + } + inline Coord( const Coord &p_coord ) : x(p_coord.x), y(p_coord.y) + { + } + inline int &X() { return( x ); } + inline const int &X() const { return( x ); } + inline int &Y() { return( y ); } + inline const int &Y() const { return( y ); } - inline static Coord Range( const Coord &coord1, const Coord &coord2 ) - { - Coord result( (coord1.x-coord2.x)+1, (coord1.y-coord2.y)+1 ); - return( result ); - } + inline static Coord Range( const Coord &coord1, const Coord &coord2 ) + { + Coord result( (coord1.x-coord2.x)+1, (coord1.y-coord2.y)+1 ); + return( result ); + } - inline bool operator==( const Coord &coord ) { return( x == coord.x && y == coord.y ); } - inline bool operator!=( const Coord &coord ) { return( x != coord.x || y != coord.y ); } - inline bool operator>( const Coord &coord ) { return( x > coord.x && y > coord.y ); } - inline bool operator>=( const Coord &coord ) { return( !(operator<(coord)) ); } - inline bool operator<( const Coord &coord ) { return( x < coord.x && y < coord.y ); } - inline bool operator<=( const Coord &coord ) { return( !(operator>(coord)) ); } - inline Coord &operator+=( const Coord &coord ) { x += coord.x; y += coord.y; return( *this ); } - inline Coord &operator-=( const Coord &coord ) { x -= coord.x; y -= coord.y; return( *this ); } + inline bool operator==( const Coord &coord ) { return( x == coord.x && y == coord.y ); } + inline bool operator!=( const Coord &coord ) { return( x != coord.x || y != coord.y ); } + inline bool operator>( const Coord &coord ) { return( x > coord.x && y > coord.y ); } + inline bool operator>=( const Coord &coord ) { return( !(operator<(coord)) ); } + inline bool operator<( const Coord &coord ) { return( x < coord.x && y < coord.y ); } + inline bool operator<=( const Coord &coord ) { return( !(operator>(coord)) ); } + inline Coord &operator+=( const Coord &coord ) { x += coord.x; y += coord.y; return( *this ); } + inline Coord &operator-=( const Coord &coord ) { x -= coord.x; y -= coord.y; return( *this ); } - inline friend Coord operator+( const Coord &coord1, const Coord &coord2 ) { Coord result( coord1 ); result += coord2; return( result ); } - inline friend Coord operator-( const Coord &coord1, const Coord &coord2 ) { Coord result( coord1 ); result -= coord2; return( result ); } + inline friend Coord operator+( const Coord &coord1, const Coord &coord2 ) { Coord result( coord1 ); result += coord2; return( result ); } + inline friend Coord operator-( const Coord &coord1, const Coord &coord2 ) { Coord result( coord1 ); result -= coord2; return( result ); } }; #endif // ZM_COORD_H diff --git a/src/zm_db.cpp b/src/zm_db.cpp index a342ca14b..f157c7ab7 100644 --- a/src/zm_db.cpp +++ b/src/zm_db.cpp @@ -29,85 +29,104 @@ int zmDbConnected = false; void zmDbConnect() { - if ( !mysql_init( &dbconn ) ) - { - Error( "Can't initialise database connection: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - my_bool reconnect = 1; - if ( mysql_options( &dbconn, MYSQL_OPT_RECONNECT, &reconnect ) ) - Fatal( "Can't set database auto reconnect option: %s", mysql_error( &dbconn ) ); - std::string::size_type colonIndex = staticConfig.DB_HOST.find( ":/" ); - if ( colonIndex != std::string::npos ) + if ( !mysql_init( &dbconn ) ) + { + Error( "Can't initialise database connection: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + my_bool reconnect = 1; + if ( mysql_options( &dbconn, MYSQL_OPT_RECONNECT, &reconnect ) ) + Fatal( "Can't set database auto reconnect option: %s", mysql_error( &dbconn ) ); + std::string::size_type colonIndex = staticConfig.DB_HOST.find( ":/" ); + if ( colonIndex != std::string::npos ) + { + std::string dbHost = staticConfig.DB_HOST.substr( 0, colonIndex ); + std::string dbPort = staticConfig.DB_HOST.substr( colonIndex+1 ); + if ( !mysql_real_connect( &dbconn, dbHost.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), 0, atoi(dbPort.c_str()), 0, 0 ) ) { - std::string dbHost = staticConfig.DB_HOST.substr( 0, colonIndex ); - std::string dbPort = staticConfig.DB_HOST.substr( colonIndex+1 ); - if ( !mysql_real_connect( &dbconn, dbHost.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), 0, atoi(dbPort.c_str()), 0, 0 ) ) - { - Error( "Can't connect to server: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + Error( "Can't connect to server: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); } - else + } + else + { + if ( !mysql_real_connect( &dbconn, staticConfig.DB_HOST.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), 0, 0, 0, 0 ) ) { - if ( !mysql_real_connect( &dbconn, staticConfig.DB_HOST.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), 0, 0, 0, 0 ) ) - { - Error( "Can't connect to server: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + Error( "Can't connect to server: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); } - if ( mysql_select_db( &dbconn, staticConfig.DB_NAME.c_str() ) ) - { - Error( "Can't select database: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - zmDbConnected = true; + } + if ( mysql_select_db( &dbconn, staticConfig.DB_NAME.c_str() ) ) + { + Error( "Can't select database: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + zmDbConnected = true; } void zmDbClose() { - if ( zmDbConnected ) - { - mysql_close( &dbconn ); - // mysql_init() call implicitly mysql_library_init() but - // mysql_close() does not call mysql_library_end() - mysql_library_end(); - zmDbConnected = false; - } + if ( zmDbConnected ) + { + mysql_close( &dbconn ); + // mysql_init() call implicitly mysql_library_init() but + // mysql_close() does not call mysql_library_end() + mysql_library_end(); + zmDbConnected = false; + } } MYSQL_RES * zmDbFetch( const char * query ) { - if ( ! zmDbConnected ) { - Error( "Not connected." ); - return NULL; - } + if ( ! zmDbConnected ) { + Error( "Not connected." ); + return NULL; + } - if ( mysql_query( &dbconn, query ) ) { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - return NULL; - } - Debug( 4, "Success running query: %s", query ); - MYSQL_RES *result = mysql_store_result( &dbconn ); - if ( !result ) { - Error( "Can't use query result: %s for query %s", mysql_error( &dbconn ), query ); - return NULL; - } - return result; + if ( mysql_query( &dbconn, query ) ) { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + return NULL; + } + Debug( 4, "Success running query: %s", query ); + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) { + Error( "Can't use query result: %s for query %s", mysql_error( &dbconn ), query ); + return NULL; + } + return result; } // end MYSQL_RES * zmDbFetch( const char * query ); -MYSQL_ROW zmDbFetchOne( const char *query ) { - MYSQL_RES *result = zmDbFetch( query ); - int n_rows = mysql_num_rows( result ); - if ( n_rows != 1 ) { - Error( "Bogus number of lines return from query, %d returned for query %s.", n_rows, query ); - return NULL; - } - - MYSQL_ROW dbrow = mysql_fetch_row( result ); - mysql_free_result( result ); - if ( ! dbrow ) { - Error("Error getting row from query %s. Error is %s", query, mysql_error( &dbconn ) ); - return NULL; - } - return dbrow; +zmDbRow *zmDbFetchOne( const char *query ) { + zmDbRow *row = new zmDbRow(); + if ( row->fetch( query ) ) { + return row; + } + delete row; + return NULL; +} + +MYSQL_RES *zmDbRow::fetch( const char *query ) { + result_set = zmDbFetch( query ); + if ( ! result_set ) return result_set; + + int n_rows = mysql_num_rows( result_set ); + if ( n_rows != 1 ) { + Error( "Bogus number of lines return from query, %d returned for query %s.", n_rows, query ); + mysql_free_result( result_set ); + result_set = NULL; + return result_set; + } + + row = mysql_fetch_row( result_set ); + if ( ! row ) { + mysql_free_result( result_set ); + result_set = NULL; + Error("Error getting row from query %s. Error is %s", query, mysql_error( &dbconn ) ); + } else { + Debug(3, "Succes"); + } + return result_set; +} +zmDbRow::~zmDbRow() { + if ( result_set ) + mysql_free_result( result_set ); } diff --git a/src/zm_db.h b/src/zm_db.h index 6ec1b5e4e..50ae2974f 100644 --- a/src/zm_db.h +++ b/src/zm_db.h @@ -22,6 +22,21 @@ #include +class zmDbRow { + private: + MYSQL_RES *result_set; + MYSQL_ROW row; + public: + zmDbRow() { result_set = NULL; row = NULL; }; + MYSQL_RES *fetch( const char *query ); + zmDbRow( MYSQL_RES *, MYSQL_ROW *row ); + ~zmDbRow(); + + char *operator[](unsigned int index) const { + return row[index]; + } +}; + #ifdef __cplusplus extern "C" { #endif @@ -33,7 +48,7 @@ void zmDbConnect(); void zmDbClose(); MYSQL_RES * zmDbFetch( const char *query ); -MYSQL_ROW zmDbFetchOne( const char *query ); +zmDbRow *zmDbFetchOne( const char *query ); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 6cff9456e..50baea77e 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -60,1575 +60,1575 @@ int Event::pre_alarm_count = 0; Event::PreAlarmData Event::pre_alarm_data[MAX_PRE_ALARM_FRAMES] = { { 0 } }; Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string &p_cause, const StringSetMap &p_noteSetMap, bool p_videoEvent ) : - monitor( p_monitor ), - start_time( p_start_time ), - cause( p_cause ), - noteSetMap( p_noteSetMap ), - videoEvent( p_videoEvent ), - videowriter( NULL ) + monitor( p_monitor ), + start_time( p_start_time ), + cause( p_cause ), + noteSetMap( p_noteSetMap ), + videoEvent( p_videoEvent ), + videowriter( NULL ) { - if ( !initialised ) - Initialise(); + if ( !initialised ) + Initialise(); - std::string notes; - createNotes( notes ); + std::string notes; + createNotes( notes ); - bool untimedEvent = false; - if ( !start_time.tv_sec ) + bool untimedEvent = false; + if ( !start_time.tv_sec ) + { + untimedEvent = true; + gettimeofday( &start_time, 0 ); + } + + Storage * storage = monitor->getStorage(); + + static char sql[ZM_SQL_MED_BUFSIZ]; + + struct tm *stime = localtime( &start_time.tv_sec ); + snprintf( sql, sizeof(sql), "insert into Events ( MonitorId, StorageId, Name, StartTime, Width, Height, Cause, Notes, Videoed ) values ( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d )", monitor->Id(), storage->Id(), start_time.tv_sec, monitor->Width(), monitor->Height(), cause.c_str(), notes.c_str(), videoEvent ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't insert event: %s. sql was (%s)", mysql_error( &dbconn ), sql ); + exit( mysql_errno( &dbconn ) ); + } + id = mysql_insert_id( &dbconn ); + if ( untimedEvent ) + { + Warning( "Event %d has zero time, setting to current", id ); + } + end_time.tv_sec = 0; + frames = 0; + alarm_frames = 0; + tot_score = 0; + max_score = 0; + + if ( config.use_deep_storage ) + { + char *path_ptr = path; + path_ptr += snprintf( path_ptr, sizeof(path), "%s/%d", storage->Path(), monitor->Id() ); + + int dt_parts[6]; + dt_parts[0] = stime->tm_year-100; + dt_parts[1] = stime->tm_mon+1; + dt_parts[2] = stime->tm_mday; + dt_parts[3] = stime->tm_hour; + dt_parts[4] = stime->tm_min; + dt_parts[5] = stime->tm_sec; + + char date_path[PATH_MAX] = ""; + char time_path[PATH_MAX] = ""; + char *time_path_ptr = time_path; + for ( unsigned int i = 0; i < sizeof(dt_parts)/sizeof(*dt_parts); i++ ) { - untimedEvent = true; - gettimeofday( &start_time, 0 ); - } + path_ptr += snprintf( path_ptr, sizeof(path)-(path_ptr-path), "/%02d", dt_parts[i] ); - Storage * storage = monitor->getStorage(); - - static char sql[ZM_SQL_MED_BUFSIZ]; - - struct tm *stime = localtime( &start_time.tv_sec ); - snprintf( sql, sizeof(sql), "insert into Events ( MonitorId, StorageId, Name, StartTime, Width, Height, Cause, Notes, Videoed ) values ( %d, %d, 'New Event', from_unixtime( %ld ), %d, %d, '%s', '%s', %d )", monitor->Id(), storage->Id(), start_time.tv_sec, monitor->Width(), monitor->Height(), cause.c_str(), notes.c_str(), videoEvent ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't insert event: %s. sql was (%s)", mysql_error( &dbconn ), sql ); - exit( mysql_errno( &dbconn ) ); - } - id = mysql_insert_id( &dbconn ); - if ( untimedEvent ) - { - Warning( "Event %d has zero time, setting to current", id ); - } - end_time.tv_sec = 0; - frames = 0; - alarm_frames = 0; - tot_score = 0; - max_score = 0; - - if ( config.use_deep_storage ) - { - char *path_ptr = path; - path_ptr += snprintf( path_ptr, sizeof(path), "%s/%d", storage->Path(), monitor->Id() ); - - int dt_parts[6]; - dt_parts[0] = stime->tm_year-100; - dt_parts[1] = stime->tm_mon+1; - dt_parts[2] = stime->tm_mday; - dt_parts[3] = stime->tm_hour; - dt_parts[4] = stime->tm_min; - dt_parts[5] = stime->tm_sec; - - char date_path[PATH_MAX] = ""; - char time_path[PATH_MAX] = ""; - char *time_path_ptr = time_path; - for ( unsigned int i = 0; i < sizeof(dt_parts)/sizeof(*dt_parts); i++ ) - { - path_ptr += snprintf( path_ptr, sizeof(path)-(path_ptr-path), "/%02d", dt_parts[i] ); - - struct stat statbuf; - errno = 0; - if ( stat( path, &statbuf ) ) { - if ( errno == ENOENT || errno == ENOTDIR ) - { - if ( mkdir( path, 0755 ) ) - { - Fatal( "Can't mkdir %s: %s", path, strerror(errno)); - } - } else { - Warning( "Error stat'ing %s, may be fatal. error is %s", path, strerror(errno)); - } - } - if ( i == 2 ) - strncpy( date_path, path, sizeof(date_path) ); - else if ( i >= 3 ) - time_path_ptr += snprintf( time_path_ptr, sizeof(time_path)-(time_path_ptr-time_path), "%s%02d", i>3?"/":"", dt_parts[i] ); - } - char id_file[PATH_MAX]; - // Create event id symlink - snprintf( id_file, sizeof(id_file), "%s/.%d", date_path, id ); - if ( symlink( time_path, id_file ) < 0 ) - Fatal( "Can't symlink %s -> %s: %s", id_file, path, strerror(errno)); - // Create empty id tag file - snprintf( id_file, sizeof(id_file), "%s/.%d", path, id ); - if ( FILE *id_fp = fopen( id_file, "w" ) ) - fclose( id_fp ); - else - Fatal( "Can't fopen %s: %s", id_file, strerror(errno)); - } - else - { - snprintf( path, sizeof(path), "%s/%d/%d", storage->Path(), monitor->Id(), id ); - - struct stat statbuf; - errno = 0; - stat( path, &statbuf ); + struct stat statbuf; + errno = 0; + if ( stat( path, &statbuf ) ) { if ( errno == ENOENT || errno == ENOTDIR ) { - if ( mkdir( path, 0755 ) ) - { - Error( "Can't mkdir %s: %s", path, strerror(errno)); - } + if ( mkdir( path, 0755 ) ) + { + Fatal( "Can't mkdir %s: %s", path, strerror(errno)); + } + } else { + Warning( "Error stat'ing %s, may be fatal. error is %s", path, strerror(errno)); } - char id_file[PATH_MAX]; - // Create empty id tag file - snprintf( id_file, sizeof(id_file), "%s/.%d", path, id ); - if ( FILE *id_fp = fopen( id_file, "w" ) ) - fclose( id_fp ); - else - Fatal( "Can't fopen %s: %s", id_file, strerror(errno)); + } + if ( i == 2 ) + strncpy( date_path, path, sizeof(date_path) ); + else if ( i >= 3 ) + time_path_ptr += snprintf( time_path_ptr, sizeof(time_path)-(time_path_ptr-time_path), "%s%02d", i>3?"/":"", dt_parts[i] ); } - last_db_frame = 0; + char id_file[PATH_MAX]; + // Create event id symlink + snprintf( id_file, sizeof(id_file), "%s/.%d", date_path, id ); + if ( symlink( time_path, id_file ) < 0 ) + Fatal( "Can't symlink %s -> %s: %s", id_file, path, strerror(errno)); + // Create empty id tag file + snprintf( id_file, sizeof(id_file), "%s/.%d", path, id ); + if ( FILE *id_fp = fopen( id_file, "w" ) ) + fclose( id_fp ); + else + Fatal( "Can't fopen %s: %s", id_file, strerror(errno)); + } + else + { + snprintf( path, sizeof(path), "%s/%d/%d", storage->Path(), monitor->Id(), id ); - video_name[0] = 0; + struct stat statbuf; + errno = 0; + stat( path, &statbuf ); + if ( errno == ENOENT || errno == ENOTDIR ) + { + if ( mkdir( path, 0755 ) ) + { + Error( "Can't mkdir %s: %s", path, strerror(errno)); + } + } + char id_file[PATH_MAX]; + // Create empty id tag file + snprintf( id_file, sizeof(id_file), "%s/.%d", path, id ); + if ( FILE *id_fp = fopen( id_file, "w" ) ) + fclose( id_fp ); + else + Fatal( "Can't fopen %s: %s", id_file, strerror(errno)); + } + last_db_frame = 0; - /* Save as video */ + video_name[0] = 0; - if ( monitor->GetOptVideoWriter() != 0 ) { - int nRet; - snprintf( video_name, sizeof(video_name), "%d-%s", id, "video.mp4" ); - snprintf( video_file, sizeof(video_file), video_file_format, path, video_name ); - snprintf( timecodes_name, sizeof(timecodes_name), "%d-%s", id, "video.timecodes" ); - snprintf( timecodes_file, sizeof(timecodes_file), video_file_format, path, timecodes_name ); + /* Save as video */ + + if ( monitor->GetOptVideoWriter() != 0 ) { + int nRet; + snprintf( video_name, sizeof(video_name), "%d-%s", id, "video.mp4" ); + snprintf( video_file, sizeof(video_file), video_file_format, path, video_name ); + snprintf( timecodes_name, sizeof(timecodes_name), "%d-%s", id, "video.timecodes" ); + snprintf( timecodes_file, sizeof(timecodes_file), video_file_format, path, timecodes_name ); - /* X264 MP4 video writer */ - if(monitor->GetOptVideoWriter() == 1) { + /* X264 MP4 video writer */ + if(monitor->GetOptVideoWriter() == 1) { #if ZM_HAVE_VIDEOWRITER_X264MP4 - videowriter = new X264MP4Writer(video_file, monitor->Width(), monitor->Height(), monitor->Colours(), monitor->SubpixelOrder(), monitor->GetOptEncoderParams()); + videowriter = new X264MP4Writer(video_file, monitor->Width(), monitor->Height(), monitor->Colours(), monitor->SubpixelOrder(), monitor->GetOptEncoderParams()); #else - videowriter = NULL; - Error("ZoneMinder was not compiled with the X264 MP4 video writer, check dependencies (x264 and mp4v2)"); + videowriter = NULL; + Error("ZoneMinder was not compiled with the X264 MP4 video writer, check dependencies (x264 and mp4v2)"); #endif - } + } - if(videowriter != NULL) { - /* Open the video stream */ - nRet = videowriter->Open(); - if(nRet != 0) { - Error("Failed opening video stream"); - delete videowriter; - videowriter = NULL; - } + if(videowriter != NULL) { + /* Open the video stream */ + nRet = videowriter->Open(); + if(nRet != 0) { + Error("Failed opening video stream"); + delete videowriter; + videowriter = NULL; + } - /* Create timecodes file */ - timecodes_fd = fopen(timecodes_file, "wb"); - if(timecodes_fd == NULL) { - Error("Failed creating timecodes file"); - } - } - } else { - /* No video object */ - videowriter = NULL; - } + /* Create timecodes file */ + timecodes_fd = fopen(timecodes_file, "wb"); + if(timecodes_fd == NULL) { + Error("Failed creating timecodes file"); + } + } + } else { + /* No video object */ + videowriter = NULL; + } } Event::~Event() { - if ( frames > last_db_frame ) - { - struct DeltaTimeval delta_time; - DELTA_TIMEVAL( delta_time, end_time, start_time, DT_PREC_2 ); - - Debug( 1, "Adding closing frame %d to DB", frames ); - static char sql[ZM_SQL_SML_BUFSIZ]; - snprintf( sql, sizeof(sql), "insert into Frames ( EventId, FrameId, TimeStamp, Delta ) values ( %d, %d, from_unixtime( %ld ), %s%ld.%02ld )", id, frames, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't insert frame: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - } - - /* Close the video file */ - if ( videowriter != NULL ) { - int nRet; - - nRet = videowriter->Close(); - if(nRet != 0) { - Error("Failed closing video stream"); - } - delete videowriter; - videowriter = NULL; - - /* Close the timecodes file */ - fclose(timecodes_fd); - timecodes_fd = NULL; - } - - static char sql[ZM_SQL_MED_BUFSIZ]; - + if ( frames > last_db_frame ) + { struct DeltaTimeval delta_time; DELTA_TIMEVAL( delta_time, end_time, start_time, DT_PREC_2 ); - snprintf( sql, sizeof(sql), "update Events set Name='%s%d', EndTime = from_unixtime( %ld ), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d, DefaultVideo = '%s' where Id = %d", monitor->EventPrefix(), id, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, video_name, id ); + Debug( 1, "Adding closing frame %d to DB", frames ); + static char sql[ZM_SQL_SML_BUFSIZ]; + snprintf( sql, sizeof(sql), "insert into Frames ( EventId, FrameId, TimeStamp, Delta ) values ( %d, %d, from_unixtime( %ld ), %s%ld.%02ld )", id, frames, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec ); if ( mysql_query( &dbconn, sql ) ) { - Error( "Can't update event: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); + Error( "Can't insert frame: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); } + } + + /* Close the video file */ + if ( videowriter != NULL ) { + int nRet; + + nRet = videowriter->Close(); + if(nRet != 0) { + Error("Failed closing video stream"); + } + delete videowriter; + videowriter = NULL; + + /* Close the timecodes file */ + fclose(timecodes_fd); + timecodes_fd = NULL; + } + + static char sql[ZM_SQL_MED_BUFSIZ]; + + struct DeltaTimeval delta_time; + DELTA_TIMEVAL( delta_time, end_time, start_time, DT_PREC_2 ); + + snprintf( sql, sizeof(sql), "update Events set Name='%s%d', EndTime = from_unixtime( %ld ), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d, DefaultVideo = '%s' where Id = %d", monitor->EventPrefix(), id, end_time.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, video_name, id ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't update event: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } } void Event::createNotes( std::string ¬es ) { - notes.clear(); - for ( StringSetMap::const_iterator mapIter = noteSetMap.begin(); mapIter != noteSetMap.end(); mapIter++ ) + notes.clear(); + for ( StringSetMap::const_iterator mapIter = noteSetMap.begin(); mapIter != noteSetMap.end(); mapIter++ ) + { + notes += mapIter->first; + notes += ": "; + const StringSet &stringSet = mapIter->second; + for ( StringSet::const_iterator setIter = stringSet.begin(); setIter != stringSet.end(); setIter++ ) { - notes += mapIter->first; - notes += ": "; - const StringSet &stringSet = mapIter->second; - for ( StringSet::const_iterator setIter = stringSet.begin(); setIter != stringSet.end(); setIter++ ) - { - if ( setIter != stringSet.begin() ) - notes += ", "; - notes += *setIter; - } + if ( setIter != stringSet.begin() ) + notes += ", "; + notes += *setIter; } + } } int Event::sd = -1; bool Event::OpenFrameSocket( int monitor_id ) { - if ( sd > 0 ) + if ( sd > 0 ) + { + close( sd ); + } + + sd = socket( AF_UNIX, SOCK_STREAM, 0); + if ( sd < 0 ) + { + Error( "Can't create socket: %s", strerror(errno) ); + return( false ); + } + + int socket_buffer_size = config.frame_socket_size; + if ( socket_buffer_size > 0 ) + { + if ( setsockopt( sd, SOL_SOCKET, SO_SNDBUF, &socket_buffer_size, sizeof(socket_buffer_size) ) < 0 ) { - close( sd ); + Error( "Can't get socket buffer size to %d, error = %s", socket_buffer_size, strerror(errno) ); + close( sd ); + sd = -1; + return( false ); } + } - sd = socket( AF_UNIX, SOCK_STREAM, 0); - if ( sd < 0 ) - { - Error( "Can't create socket: %s", strerror(errno) ); - return( false ); - } + int flags; + if ( (flags = fcntl( sd, F_GETFL )) < 0 ) + { + Error( "Can't get socket flags, error = %s", strerror(errno) ); + close( sd ); + sd = -1; + return( false ); + } + flags |= O_NONBLOCK; + if ( fcntl( sd, F_SETFL, flags ) < 0 ) + { + Error( "Can't set socket flags, error = %s", strerror(errno) ); + close( sd ); + sd = -1; + return( false ); + } - int socket_buffer_size = config.frame_socket_size; - if ( socket_buffer_size > 0 ) - { - if ( setsockopt( sd, SOL_SOCKET, SO_SNDBUF, &socket_buffer_size, sizeof(socket_buffer_size) ) < 0 ) - { - Error( "Can't get socket buffer size to %d, error = %s", socket_buffer_size, strerror(errno) ); - close( sd ); - sd = -1; - return( false ); - } - } + char sock_path[PATH_MAX] = ""; + snprintf( sock_path, sizeof(sock_path), "%s/zmf-%d.sock", config.path_socks, monitor_id ); - int flags; - if ( (flags = fcntl( sd, F_GETFL )) < 0 ) - { - Error( "Can't get socket flags, error = %s", strerror(errno) ); - close( sd ); - sd = -1; - return( false ); - } - flags |= O_NONBLOCK; - if ( fcntl( sd, F_SETFL, flags ) < 0 ) - { - Error( "Can't set socket flags, error = %s", strerror(errno) ); - close( sd ); - sd = -1; - return( false ); - } + struct sockaddr_un addr; - char sock_path[PATH_MAX] = ""; - snprintf( sock_path, sizeof(sock_path), "%s/zmf-%d.sock", config.path_socks, monitor_id ); + strncpy( addr.sun_path, sock_path, sizeof(addr.sun_path) ); + addr.sun_family = AF_UNIX; - struct sockaddr_un addr; + if ( connect( sd, (struct sockaddr *)&addr, strlen(addr.sun_path)+sizeof(addr.sun_family)) < 0 ) + { + Warning( "Can't connect to frame server: %s", strerror(errno) ); + close( sd ); + sd = -1; + return( false ); + } - strncpy( addr.sun_path, sock_path, sizeof(addr.sun_path) ); - addr.sun_family = AF_UNIX; - - if ( connect( sd, (struct sockaddr *)&addr, strlen(addr.sun_path)+sizeof(addr.sun_family)) < 0 ) - { - Warning( "Can't connect to frame server: %s", strerror(errno) ); - close( sd ); - sd = -1; - return( false ); - } - - Debug( 1, "Opened connection to frame server" ); - return( true ); + Debug( 1, "Opened connection to frame server" ); + return( true ); } bool Event::ValidateFrameSocket( int monitor_id ) { - if ( sd < 0 ) - { - return( OpenFrameSocket( monitor_id ) ); - } - return( true ); + if ( sd < 0 ) + { + return( OpenFrameSocket( monitor_id ) ); + } + return( true ); } bool Event::SendFrameImage( const Image *image, bool alarm_frame ) { - if ( !ValidateFrameSocket( monitor->Id() ) ) + if ( !ValidateFrameSocket( monitor->Id() ) ) + { + return( false ); + } + + static int jpg_buffer_size = 0; + static unsigned char jpg_buffer[ZM_MAX_IMAGE_SIZE]; + + image->EncodeJpeg( jpg_buffer, &jpg_buffer_size, (alarm_frame&&(config.jpeg_alarm_file_quality>config.jpeg_file_quality))?config.jpeg_alarm_file_quality:config.jpeg_file_quality ); + + static FrameHeader frame_header; + + frame_header.event_id = id; + if ( config.use_deep_storage ) + frame_header.event_time = start_time.tv_sec; + frame_header.frame_id = frames; + frame_header.alarm_frame = alarm_frame; + frame_header.image_length = jpg_buffer_size; + + struct iovec iovecs[2]; + iovecs[0].iov_base = &frame_header; + iovecs[0].iov_len = sizeof(frame_header); + iovecs[1].iov_base = jpg_buffer; + iovecs[1].iov_len = jpg_buffer_size; + + ssize_t writev_size = sizeof(frame_header)+jpg_buffer_size; + ssize_t writev_result = writev( sd, iovecs, sizeof(iovecs)/sizeof(*iovecs)); + if ( writev_result != writev_size ) + { + if ( writev_result < 0 ) { - return( false ); + if ( errno == EAGAIN ) + { + Warning( "Blocking write detected" ); + } + else + { + Error( "Can't write frame: %s", strerror(errno) ); + close( sd ); + sd = -1; + } } - - static int jpg_buffer_size = 0; - static unsigned char jpg_buffer[ZM_MAX_IMAGE_SIZE]; - - image->EncodeJpeg( jpg_buffer, &jpg_buffer_size, (alarm_frame&&(config.jpeg_alarm_file_quality>config.jpeg_file_quality))?config.jpeg_alarm_file_quality:config.jpeg_file_quality ); - - static FrameHeader frame_header; - - frame_header.event_id = id; - if ( config.use_deep_storage ) - frame_header.event_time = start_time.tv_sec; - frame_header.frame_id = frames; - frame_header.alarm_frame = alarm_frame; - frame_header.image_length = jpg_buffer_size; - - struct iovec iovecs[2]; - iovecs[0].iov_base = &frame_header; - iovecs[0].iov_len = sizeof(frame_header); - iovecs[1].iov_base = jpg_buffer; - iovecs[1].iov_len = jpg_buffer_size; - - ssize_t writev_size = sizeof(frame_header)+jpg_buffer_size; - ssize_t writev_result = writev( sd, iovecs, sizeof(iovecs)/sizeof(*iovecs)); - if ( writev_result != writev_size ) + else { - if ( writev_result < 0 ) - { - if ( errno == EAGAIN ) - { - Warning( "Blocking write detected" ); - } - else - { - Error( "Can't write frame: %s", strerror(errno) ); - close( sd ); - sd = -1; - } - } - else - { - Error( "Incomplete frame write: %zd of %zd bytes written", writev_result, writev_size ); - close( sd ); - sd = -1; - } - return( false ); + Error( "Incomplete frame write: %zd of %zd bytes written", writev_result, writev_size ); + close( sd ); + sd = -1; } - Debug( 1, "Wrote frame image, %d bytes", jpg_buffer_size ); + return( false ); + } + Debug( 1, "Wrote frame image, %d bytes", jpg_buffer_size ); - return( true ); + return( true ); } bool Event::WriteFrameImage( Image *image, struct timeval timestamp, const char *event_file, bool alarm_frame ) { - Image* ImgToWrite; - Image* ts_image = NULL; + Image* ImgToWrite; + Image* ts_image = NULL; - if ( config.timestamp_on_capture ) // stash the image we plan to use in another pointer regardless if timestamped. - { - ts_image = new Image(*image); - monitor->TimestampImage( ts_image, ×tamp ); - ImgToWrite=ts_image; - } - else - ImgToWrite=image; + if ( config.timestamp_on_capture ) // stash the image we plan to use in another pointer regardless if timestamped. + { + ts_image = new Image(*image); + monitor->TimestampImage( ts_image, ×tamp ); + ImgToWrite=ts_image; + } + else + ImgToWrite=image; - if ( !config.opt_frame_server || !SendFrameImage(ImgToWrite, alarm_frame) ) - { - int thisquality = ( alarm_frame && (config.jpeg_alarm_file_quality > config.jpeg_file_quality) ) ? config.jpeg_alarm_file_quality : 0 ; // quality to use, zero is default - ImgToWrite->WriteJpeg( event_file, thisquality, (monitor->Exif() ? timestamp : (timeval){0,0}) ); // exif is only timestamp at present this switches on or off for write - } - if(ts_image) delete(ts_image); // clean up if used. - return( true ); + if ( !config.opt_frame_server || !SendFrameImage(ImgToWrite, alarm_frame) ) + { + int thisquality = ( alarm_frame && (config.jpeg_alarm_file_quality > config.jpeg_file_quality) ) ? config.jpeg_alarm_file_quality : 0 ; // quality to use, zero is default + ImgToWrite->WriteJpeg( event_file, thisquality, (monitor->Exif() ? timestamp : (timeval){0,0}) ); // exif is only timestamp at present this switches on or off for write + } + if(ts_image) delete(ts_image); // clean up if used. + return( true ); } bool Event::WriteFrameVideo( const Image *image, const struct timeval timestamp, VideoWriter* videow ) { - const Image* frameimg = image; - Image ts_image; + const Image* frameimg = image; + Image ts_image; - /* Checking for invalid parameters */ - if ( videow == NULL ) { - Error("NULL Video object"); - return false; - } + /* Checking for invalid parameters */ + if ( videow == NULL ) { + Error("NULL Video object"); + return false; + } - /* If the image does not contain a timestamp, add the timestamp */ - if (!config.timestamp_on_capture) { - ts_image = *image; - monitor->TimestampImage( &ts_image, ×tamp ); - frameimg = &ts_image; - } + /* If the image does not contain a timestamp, add the timestamp */ + if (!config.timestamp_on_capture) { + ts_image = *image; + monitor->TimestampImage( &ts_image, ×tamp ); + frameimg = &ts_image; + } - /* Calculate delta time */ - struct DeltaTimeval delta_time3; - DELTA_TIMEVAL( delta_time3, timestamp, start_time, DT_PREC_3 ); - unsigned int timeMS = (delta_time3.sec * delta_time3.prec) + delta_time3.fsec; + /* Calculate delta time */ + struct DeltaTimeval delta_time3; + DELTA_TIMEVAL( delta_time3, timestamp, start_time, DT_PREC_3 ); + unsigned int timeMS = (delta_time3.sec * delta_time3.prec) + delta_time3.fsec; - /* Encode and write the frame */ - if(videowriter->Encode(frameimg, timeMS) != 0) { - Error("Failed encoding video frame"); - } + /* Encode and write the frame */ + if(videowriter->Encode(frameimg, timeMS) != 0) { + Error("Failed encoding video frame"); + } - /* Add the frame to the timecodes file */ - fprintf(timecodes_fd, "%u\n", timeMS); + /* Add the frame to the timecodes file */ + fprintf(timecodes_fd, "%u\n", timeMS); - return( true ); + return( true ); } void Event::updateNotes( const StringSetMap &newNoteSetMap ) { - bool update = false; + bool update = false; - //Info( "Checking notes, %d <> %d", noteSetMap.size(), newNoteSetMap.size() ); - if ( newNoteSetMap.size() > 0 ) + //Info( "Checking notes, %d <> %d", noteSetMap.size(), newNoteSetMap.size() ); + if ( newNoteSetMap.size() > 0 ) + { + if ( noteSetMap.size() == 0 ) { - if ( noteSetMap.size() == 0 ) + noteSetMap = newNoteSetMap; + update = true; + } + else + { + for ( StringSetMap::const_iterator newNoteSetMapIter = newNoteSetMap.begin(); newNoteSetMapIter != newNoteSetMap.end(); newNoteSetMapIter++ ) + { + const std::string &newNoteGroup = newNoteSetMapIter->first; + const StringSet &newNoteSet = newNoteSetMapIter->second; + //Info( "Got %d new strings", newNoteSet.size() ); + if ( newNoteSet.size() > 0 ) { - noteSetMap = newNoteSetMap; + StringSetMap::iterator noteSetMapIter = noteSetMap.find( newNoteGroup ); + if ( noteSetMapIter == noteSetMap.end() ) + { + //Info( "Can't find note group %s, copying %d strings", newNoteGroup.c_str(), newNoteSet.size() ); + noteSetMap.insert( StringSetMap::value_type( newNoteGroup, newNoteSet ) ); update = true; - } - else - { - for ( StringSetMap::const_iterator newNoteSetMapIter = newNoteSetMap.begin(); newNoteSetMapIter != newNoteSetMap.end(); newNoteSetMapIter++ ) + } + else + { + StringSet ¬eSet = noteSetMapIter->second; + //Info( "Found note group %s, got %d strings", newNoteGroup.c_str(), newNoteSet.size() ); + for ( StringSet::const_iterator newNoteSetIter = newNoteSet.begin(); newNoteSetIter != newNoteSet.end(); newNoteSetIter++ ) { - const std::string &newNoteGroup = newNoteSetMapIter->first; - const StringSet &newNoteSet = newNoteSetMapIter->second; - //Info( "Got %d new strings", newNoteSet.size() ); - if ( newNoteSet.size() > 0 ) - { - StringSetMap::iterator noteSetMapIter = noteSetMap.find( newNoteGroup ); - if ( noteSetMapIter == noteSetMap.end() ) - { - //Info( "Can't find note group %s, copying %d strings", newNoteGroup.c_str(), newNoteSet.size() ); - noteSetMap.insert( StringSetMap::value_type( newNoteGroup, newNoteSet ) ); - update = true; - } - else - { - StringSet ¬eSet = noteSetMapIter->second; - //Info( "Found note group %s, got %d strings", newNoteGroup.c_str(), newNoteSet.size() ); - for ( StringSet::const_iterator newNoteSetIter = newNoteSet.begin(); newNoteSetIter != newNoteSet.end(); newNoteSetIter++ ) - { - const std::string &newNote = *newNoteSetIter; - StringSet::iterator noteSetIter = noteSet.find( newNote ); - if ( noteSetIter == noteSet.end() ) - { - noteSet.insert( newNote ); - update = true; - } - } - } - } + const std::string &newNote = *newNoteSetIter; + StringSet::iterator noteSetIter = noteSet.find( newNote ); + if ( noteSetIter == noteSet.end() ) + { + noteSet.insert( newNote ); + update = true; + } } + } } + } } + } - if ( update ) - { - std::string notes; - createNotes( notes ); + if ( update ) + { + std::string notes; + createNotes( notes ); - Debug( 2, "Updating notes for event %d, '%s'", id, notes.c_str() ); - static char sql[ZM_SQL_MED_BUFSIZ]; + Debug( 2, "Updating notes for event %d, '%s'", id, notes.c_str() ); + static char sql[ZM_SQL_MED_BUFSIZ]; #if USE_PREPARED_SQL - static MYSQL_STMT *stmt = 0; + static MYSQL_STMT *stmt = 0; - char notesStr[ZM_SQL_MED_BUFSIZ] = ""; - unsigned long notesLen = 0; + char notesStr[ZM_SQL_MED_BUFSIZ] = ""; + unsigned long notesLen = 0; - if ( !stmt ) - { - const char *sql = "update Events set Notes = ? where Id = ?"; + if ( !stmt ) + { + const char *sql = "update Events set Notes = ? where Id = ?"; - stmt = mysql_stmt_init( &dbconn ); - if ( mysql_stmt_prepare( stmt, sql, strlen(sql) ) ) - { - Fatal( "Unable to prepare sql '%s': %s", sql, mysql_stmt_error(stmt) ); - } + stmt = mysql_stmt_init( &dbconn ); + if ( mysql_stmt_prepare( stmt, sql, strlen(sql) ) ) + { + Fatal( "Unable to prepare sql '%s': %s", sql, mysql_stmt_error(stmt) ); + } - /* Get the parameter count from the statement */ - if ( mysql_stmt_param_count( stmt ) != 2 ) - { - Fatal( "Unexpected parameter count %ld in sql '%s'", mysql_stmt_param_count( stmt ), sql ); - } + /* Get the parameter count from the statement */ + if ( mysql_stmt_param_count( stmt ) != 2 ) + { + Fatal( "Unexpected parameter count %ld in sql '%s'", mysql_stmt_param_count( stmt ), sql ); + } - MYSQL_BIND bind[2]; - memset(bind, 0, sizeof(bind)); + MYSQL_BIND bind[2]; + memset(bind, 0, sizeof(bind)); - /* STRING PARAM */ - bind[0].buffer_type = MYSQL_TYPE_STRING; - bind[0].buffer = (char *)notesStr; - bind[0].buffer_length = sizeof(notesStr); - bind[0].is_null = 0; - bind[0].length = ¬esLen; + /* STRING PARAM */ + bind[0].buffer_type = MYSQL_TYPE_STRING; + bind[0].buffer = (char *)notesStr; + bind[0].buffer_length = sizeof(notesStr); + bind[0].is_null = 0; + bind[0].length = ¬esLen; - bind[1].buffer_type= MYSQL_TYPE_LONG; - bind[1].buffer= (char *)&id; - bind[1].is_null= 0; - bind[1].length= 0; + bind[1].buffer_type= MYSQL_TYPE_LONG; + bind[1].buffer= (char *)&id; + bind[1].is_null= 0; + bind[1].length= 0; - /* Bind the buffers */ - if ( mysql_stmt_bind_param( stmt, bind ) ) - { - Fatal( "Unable to bind sql '%s': %s", sql, mysql_stmt_error(stmt) ); - } - } - - strncpy( notesStr, notes.c_str(), sizeof(notesStr) ); - notesLen = notes.length(); - - if ( mysql_stmt_execute( stmt ) ) - { - Fatal( "Unable to execute sql '%s': %s", sql, mysql_stmt_error(stmt) ); - } -#else - static char escapedNotes[ZM_SQL_MED_BUFSIZ]; - - mysql_real_escape_string( &dbconn, escapedNotes, notes.c_str(), notes.length() ); - - snprintf( sql, sizeof(sql), "update Events set Notes = '%s' where Id = %d", escapedNotes, id ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't insert event: %s", mysql_error( &dbconn ) ); - } -#endif + /* Bind the buffers */ + if ( mysql_stmt_bind_param( stmt, bind ) ) + { + Fatal( "Unable to bind sql '%s': %s", sql, mysql_stmt_error(stmt) ); + } } + + strncpy( notesStr, notes.c_str(), sizeof(notesStr) ); + notesLen = notes.length(); + + if ( mysql_stmt_execute( stmt ) ) + { + Fatal( "Unable to execute sql '%s': %s", sql, mysql_stmt_error(stmt) ); + } +#else + static char escapedNotes[ZM_SQL_MED_BUFSIZ]; + + mysql_real_escape_string( &dbconn, escapedNotes, notes.c_str(), notes.length() ); + + snprintf( sql, sizeof(sql), "update Events set Notes = '%s' where Id = %d", escapedNotes, id ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't insert event: %s", mysql_error( &dbconn ) ); + } +#endif + } } void Event::AddFrames( int n_frames, Image **images, struct timeval **timestamps ) { - for (int i = 0; i < n_frames; i += ZM_SQL_BATCH_SIZE) { - AddFramesInternal(n_frames, i, images, timestamps); - } + for (int i = 0; i < n_frames; i += ZM_SQL_BATCH_SIZE) { + AddFramesInternal(n_frames, i, images, timestamps); + } } void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps ) { - static char sql[ZM_SQL_LGE_BUFSIZ]; - strncpy( sql, "insert into Frames ( EventId, FrameId, TimeStamp, Delta ) values ", sizeof(sql) ); - int frameCount = 0; - for ( int i = start_frame; i < n_frames && i - start_frame < ZM_SQL_BATCH_SIZE; i++ ) + static char sql[ZM_SQL_LGE_BUFSIZ]; + strncpy( sql, "insert into Frames ( EventId, FrameId, TimeStamp, Delta ) values ", sizeof(sql) ); + int frameCount = 0; + for ( int i = start_frame; i < n_frames && i - start_frame < ZM_SQL_BATCH_SIZE; i++ ) + { + if ( !timestamps[i]->tv_sec ) { - if ( !timestamps[i]->tv_sec ) - { - Debug( 1, "Not adding pre-capture frame %d, zero timestamp", i ); - continue; - } - - frames++; - - static char event_file[PATH_MAX]; - snprintf( event_file, sizeof(event_file), capture_file_format, path, frames ); - if ( monitor->GetOptSaveJPEGs() & 4) { - //If this is the first frame, we should add a thumbnail to the event directory - if(frames == 10){ - char snapshot_file[PATH_MAX]; - snprintf( snapshot_file, sizeof(snapshot_file), "%s/snapshot.jpg", path ); - WriteFrameImage( images[i], *(timestamps[i]), snapshot_file ); - } - } - if ( monitor->GetOptSaveJPEGs() & 1) { - Debug( 1, "Writing pre-capture frame %d", frames ); - WriteFrameImage( images[i], *(timestamps[i]), event_file ); - } - if ( videowriter != NULL ) { - WriteFrameVideo( images[i], *(timestamps[i]), videowriter ); - } - - struct DeltaTimeval delta_time; - DELTA_TIMEVAL( delta_time, *(timestamps[i]), start_time, DT_PREC_2 ); - - int sql_len = strlen(sql); - snprintf( sql+sql_len, sizeof(sql)-sql_len, "( %d, %d, from_unixtime(%ld), %s%ld.%02ld ), ", id, frames, timestamps[i]->tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec ); - - frameCount++; - } - - if ( frameCount ) - { - Debug( 1, "Adding %d/%d frames to DB", frameCount, n_frames ); - *(sql+strlen(sql)-2) = '\0'; - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't insert frames: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - last_db_frame = frames; - } - else - { - Debug( 1, "No valid pre-capture frames to add" ); - } -} - -void Event::AddFrame( Image *image, struct timeval timestamp, int score, Image *alarm_image ) -{ - if ( !timestamp.tv_sec ) - { - Debug( 1, "Not adding new frame, zero timestamp" ); - return; + Debug( 1, "Not adding pre-capture frame %d, zero timestamp", i ); + continue; } frames++; static char event_file[PATH_MAX]; snprintf( event_file, sizeof(event_file), capture_file_format, path, frames ); - if ( monitor->GetOptSaveJPEGs() & 4) { - //If this is the first frame, we should add a thumbnail to the event directory - if(frames == 10){ - char snapshot_file[PATH_MAX]; - snprintf( snapshot_file, sizeof(snapshot_file), "%s/snapshot.jpg", path ); - WriteFrameImage( image, timestamp, snapshot_file ); - } + //If this is the first frame, we should add a thumbnail to the event directory + if(frames == 10){ + char snapshot_file[PATH_MAX]; + snprintf( snapshot_file, sizeof(snapshot_file), "%s/snapshot.jpg", path ); + WriteFrameImage( images[i], *(timestamps[i]), snapshot_file ); + } } - if( monitor->GetOptSaveJPEGs() & 1) { - Debug( 1, "Writing capture frame %d", frames ); - WriteFrameImage( image, timestamp, event_file ); + if ( monitor->GetOptSaveJPEGs() & 1) { + Debug( 1, "Writing pre-capture frame %d", frames ); + WriteFrameImage( images[i], *(timestamps[i]), event_file ); } if ( videowriter != NULL ) { - WriteFrameVideo( image, timestamp, videowriter ); + WriteFrameVideo( images[i], *(timestamps[i]), videowriter ); } struct DeltaTimeval delta_time; - DELTA_TIMEVAL( delta_time, timestamp, start_time, DT_PREC_2 ); + DELTA_TIMEVAL( delta_time, *(timestamps[i]), start_time, DT_PREC_2 ); - const char *frame_type = score>0?"Alarm":(score<0?"Bulk":"Normal"); - if ( score < 0 ) - score = 0; + int sql_len = strlen(sql); + snprintf( sql+sql_len, sizeof(sql)-sql_len, "( %d, %d, from_unixtime(%ld), %s%ld.%02ld ), ", id, frames, timestamps[i]->tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec ); - bool db_frame = (strcmp(frame_type,"Bulk") != 0) || ((frames%config.bulk_frame_interval)==0) || !frames; - if ( db_frame ) + frameCount++; + } + + if ( frameCount ) + { + Debug( 1, "Adding %d/%d frames to DB", frameCount, n_frames ); + *(sql+strlen(sql)-2) = '\0'; + if ( mysql_query( &dbconn, sql ) ) { - - Debug( 1, "Adding frame %d of type \"%s\" to DB", frames, frame_type ); - static char sql[ZM_SQL_MED_BUFSIZ]; - snprintf( sql, sizeof(sql), "insert into Frames ( EventId, FrameId, Type, TimeStamp, Delta, Score ) values ( %d, %d, '%s', from_unixtime( %ld ), %s%ld.%02ld, %d )", id, frames, frame_type, timestamp.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, score ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't insert frame: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - last_db_frame = frames; - - // We are writing a Bulk frame - if ( !strcmp( frame_type,"Bulk") ) - { - snprintf( sql, sizeof(sql), "update Events set Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d where Id = %d", delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, id ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't update event: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - } + Error( "Can't insert frames: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); } + last_db_frame = frames; + } + else + { + Debug( 1, "No valid pre-capture frames to add" ); + } +} - end_time = timestamp; +void Event::AddFrame( Image *image, struct timeval timestamp, int score, Image *alarm_image ) +{ + if ( !timestamp.tv_sec ) + { + Debug( 1, "Not adding new frame, zero timestamp" ); + return; + } - // We are writing an Alarm frame - if ( !strcmp( frame_type,"Alarm") ) + frames++; + + static char event_file[PATH_MAX]; + snprintf( event_file, sizeof(event_file), capture_file_format, path, frames ); + + if ( monitor->GetOptSaveJPEGs() & 4) { + //If this is the first frame, we should add a thumbnail to the event directory + if(frames == 10){ + char snapshot_file[PATH_MAX]; + snprintf( snapshot_file, sizeof(snapshot_file), "%s/snapshot.jpg", path ); + WriteFrameImage( image, timestamp, snapshot_file ); + } + } + if( monitor->GetOptSaveJPEGs() & 1) { + Debug( 1, "Writing capture frame %d", frames ); + WriteFrameImage( image, timestamp, event_file ); + } + if ( videowriter != NULL ) { + WriteFrameVideo( image, timestamp, videowriter ); + } + + struct DeltaTimeval delta_time; + DELTA_TIMEVAL( delta_time, timestamp, start_time, DT_PREC_2 ); + + const char *frame_type = score>0?"Alarm":(score<0?"Bulk":"Normal"); + if ( score < 0 ) + score = 0; + + bool db_frame = (strcmp(frame_type,"Bulk") != 0) || ((frames%config.bulk_frame_interval)==0) || !frames; + if ( db_frame ) + { + + Debug( 1, "Adding frame %d of type \"%s\" to DB", frames, frame_type ); + static char sql[ZM_SQL_MED_BUFSIZ]; + snprintf( sql, sizeof(sql), "insert into Frames ( EventId, FrameId, Type, TimeStamp, Delta, Score ) values ( %d, %d, '%s', from_unixtime( %ld ), %s%ld.%02ld, %d )", id, frames, frame_type, timestamp.tv_sec, delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, score ); + if ( mysql_query( &dbconn, sql ) ) { - alarm_frames++; - - tot_score += score; - if ( score > (int)max_score ) - max_score = score; - - if ( alarm_image ) - { - snprintf( event_file, sizeof(event_file), analyse_file_format, path, frames ); - - Debug( 1, "Writing analysis frame %d", frames ); - if ( monitor->GetOptSaveJPEGs() & 2) { - WriteFrameImage( alarm_image, timestamp, event_file, true ); - } - } + Error( "Can't insert frame: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); } - - /* This makes viewing the diagnostic images impossible because it keeps deleting them - if ( config.record_diag_images ) + last_db_frame = frames; + + // We are writing a Bulk frame + if ( !strcmp( frame_type,"Bulk") ) { - char diag_glob[PATH_MAX] = ""; - - snprintf( diag_glob, sizeof(diag_glob), "%s/%d/diag-*.jpg", config.dir_events, monitor->Id() ); - glob_t pglob; - int glob_status = glob( diag_glob, 0, 0, &pglob ); - if ( glob_status != 0 ) - { - if ( glob_status < 0 ) - { - Error( "Can't glob '%s': %s", diag_glob, strerror(errno) ); - } - else - { - Debug( 1, "Can't glob '%s': %d", diag_glob, glob_status ); - } - } - else - { - char new_diag_path[PATH_MAX] = ""; - for ( int i = 0; i < pglob.gl_pathc; i++ ) - { - char *diag_path = pglob.gl_pathv[i]; - - char *diag_file = strstr( diag_path, "diag-" ); - - if ( diag_file ) - { - snprintf( new_diag_path, sizeof(new_diag_path), general_file_format, path, frames, diag_file ); - - if ( rename( diag_path, new_diag_path ) < 0 ) - { - Error( "Can't rename '%s' to '%s': %s", diag_path, new_diag_path, strerror(errno) ); - } - } - } - } - globfree( &pglob ); + snprintf( sql, sizeof(sql), "update Events set Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d where Id = %d", delta_time.positive?"":"-", delta_time.sec, delta_time.fsec, frames, alarm_frames, tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score, id ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't update event: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } } - */ + } + + end_time = timestamp; + + // We are writing an Alarm frame + if ( !strcmp( frame_type,"Alarm") ) + { + alarm_frames++; + + tot_score += score; + if ( score > (int)max_score ) + max_score = score; + + if ( alarm_image ) + { + snprintf( event_file, sizeof(event_file), analyse_file_format, path, frames ); + + Debug( 1, "Writing analysis frame %d", frames ); + if ( monitor->GetOptSaveJPEGs() & 2) { + WriteFrameImage( alarm_image, timestamp, event_file, true ); + } + } + } + + /* This makes viewing the diagnostic images impossible because it keeps deleting them + if ( config.record_diag_images ) + { + char diag_glob[PATH_MAX] = ""; + + snprintf( diag_glob, sizeof(diag_glob), "%s/%d/diag-*.jpg", config.dir_events, monitor->Id() ); + glob_t pglob; + int glob_status = glob( diag_glob, 0, 0, &pglob ); + if ( glob_status != 0 ) + { + if ( glob_status < 0 ) + { + Error( "Can't glob '%s': %s", diag_glob, strerror(errno) ); + } + else + { + Debug( 1, "Can't glob '%s': %d", diag_glob, glob_status ); + } + } + else + { + char new_diag_path[PATH_MAX] = ""; + for ( int i = 0; i < pglob.gl_pathc; i++ ) + { + char *diag_path = pglob.gl_pathv[i]; + + char *diag_file = strstr( diag_path, "diag-" ); + + if ( diag_file ) + { + snprintf( new_diag_path, sizeof(new_diag_path), general_file_format, path, frames, diag_file ); + + if ( rename( diag_path, new_diag_path ) < 0 ) + { + Error( "Can't rename '%s' to '%s': %s", diag_path, new_diag_path, strerror(errno) ); + } + } + } + } + globfree( &pglob ); + } + */ } bool EventStream::loadInitialEventData( int monitor_id, time_t event_time ) { - static char sql[ZM_SQL_SML_BUFSIZ]; + static char sql[ZM_SQL_SML_BUFSIZ]; - snprintf( sql, sizeof(sql), "select Id from Events where MonitorId = %d and unix_timestamp( EndTime ) > %ld order by Id asc limit 1", monitor_id, event_time ); + snprintf( sql, sizeof(sql), "select Id from Events where MonitorId = %d and unix_timestamp( EndTime ) > %ld order by Id asc limit 1", monitor_id, event_time ); - if ( mysql_query( &dbconn, sql ) ) + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) + { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + MYSQL_ROW dbrow = mysql_fetch_row( result ); + + if ( mysql_errno( &dbconn ) ) + { + Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + + int init_event_id = atoi( dbrow[0] ); + + mysql_free_result( result ); + + loadEventData( init_event_id ); + + if ( event_time ) + { + curr_stream_time = event_time; + curr_frame_id = 1; + if ( event_time >= event_data->start_time ) { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - - MYSQL_RES *result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - MYSQL_ROW dbrow = mysql_fetch_row( result ); - - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - - int init_event_id = atoi( dbrow[0] ); - - mysql_free_result( result ); - - loadEventData( init_event_id ); - - if ( event_time ) - { - curr_stream_time = event_time; - curr_frame_id = 1; - if ( event_time >= event_data->start_time ) + for (unsigned int i = 0; i < event_data->frame_count; i++ ) + { + //Info( "eft %d > et %d", event_data->frames[i].timestamp, event_time ); + if ( event_data->frames[i].timestamp >= event_time ) { - for (unsigned int i = 0; i < event_data->frame_count; i++ ) - { - //Info( "eft %d > et %d", event_data->frames[i].timestamp, event_time ); - if ( event_data->frames[i].timestamp >= event_time ) - { - curr_frame_id = i+1; - Debug( 3, "Set cst:%.2f", curr_stream_time ); - Debug( 3, "Set cfid:%d", curr_frame_id ); - break; - } - } - Debug( 3, "Skipping %ld frames", event_data->frame_count ); + curr_frame_id = i+1; + Debug( 3, "Set cst:%.2f", curr_stream_time ); + Debug( 3, "Set cfid:%d", curr_frame_id ); + break; } + } + Debug( 3, "Skipping %ld frames", event_data->frame_count ); } - return( true ); + } + return( true ); } -bool EventStream::loadInitialEventData( int init_event_id, int init_frame_id ) +bool EventStream::loadInitialEventData( int init_event_id, unsigned int init_frame_id ) { - loadEventData( init_event_id ); + loadEventData( init_event_id ); - if ( init_frame_id ) - { - curr_stream_time = event_data->frames[init_frame_id-1].timestamp; - curr_frame_id = init_frame_id; - } - else - { - curr_stream_time = event_data->start_time; - } + if ( init_frame_id ) + { + curr_stream_time = event_data->frames[init_frame_id-1].timestamp; + curr_frame_id = init_frame_id; + } + else + { + curr_stream_time = event_data->start_time; + } - return( true ); + return( true ); } bool EventStream::loadEventData( int event_id ) { - static char sql[ZM_SQL_MED_BUFSIZ]; + static char sql[ZM_SQL_MED_BUFSIZ]; - snprintf( sql, sizeof(sql), "select M.Id, M.Name, E.StorageId, E.Frames, unix_timestamp( StartTime ) as StartTimestamp, max(F.Delta)-min(F.Delta) as Duration,E.DefaultVideo from Events as E inner join Monitors as M on E.MonitorId = M.Id inner join Frames as F on E.Id = F.EventId where E.Id = %d group by E.Id", event_id ); + snprintf( sql, sizeof(sql), "select M.Id, M.Name, E.StorageId, E.Frames, unix_timestamp( StartTime ) as StartTimestamp, max(F.Delta)-min(F.Delta) as Duration,E.DefaultVideo from Events as E inner join Monitors as M on E.MonitorId = M.Id inner join Frames as F on E.Id = F.EventId where E.Id = %d group by E.Id", event_id ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - MYSQL_RES *result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) + { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - if ( !mysql_num_rows( result ) ) - { - Fatal( "Unable to load event %d, not found in DB", event_id ); - } + if ( !mysql_num_rows( result ) ) + { + Fatal( "Unable to load event %d, not found in DB", event_id ); + } - MYSQL_ROW dbrow = mysql_fetch_row( result ); + MYSQL_ROW dbrow = mysql_fetch_row( result ); - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + if ( mysql_errno( &dbconn ) ) + { + Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - delete event_data; - event_data = new EventData; - event_data->event_id = event_id; - event_data->monitor_id = atoi( dbrow[0] ); - event_data->storage_id = dbrow[2] ? atoi( dbrow[2] ) : 0; - event_data->start_time = atoi(dbrow[4]); + delete event_data; + event_data = new EventData; + event_data->event_id = event_id; + event_data->monitor_id = atoi( dbrow[0] ); + event_data->storage_id = dbrow[2] ? atoi( dbrow[2] ) : 0; + event_data->start_time = atoi(dbrow[4]); - Storage * storage = new Storage( event_data->storage_id ); - const char *storage_path = storage->Path(); + Storage * storage = new Storage( event_data->storage_id ); + const char *storage_path = storage->Path(); - if ( config.use_deep_storage ) - { - struct tm *event_time = localtime( &event_data->start_time ); - if ( storage_path[0] == '/' ) - snprintf( event_data->path, sizeof(event_data->path), "%s/%ld/%02d/%02d/%02d/%02d/%02d/%02d", storage_path, event_data->monitor_id, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_hour, event_time->tm_min, event_time->tm_sec ); - else - snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%02d/%02d/%02d/%02d/%02d/%02d", staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_hour, event_time->tm_min, event_time->tm_sec ); - } + if ( config.use_deep_storage ) + { + struct tm *event_time = localtime( &event_data->start_time ); + if ( storage_path[0] == '/' ) + snprintf( event_data->path, sizeof(event_data->path), "%s/%ld/%02d/%02d/%02d/%02d/%02d/%02d", storage_path, event_data->monitor_id, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_hour, event_time->tm_min, event_time->tm_sec ); else + snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%02d/%02d/%02d/%02d/%02d/%02d", staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, event_time->tm_year-100, event_time->tm_mon+1, event_time->tm_mday, event_time->tm_hour, event_time->tm_min, event_time->tm_sec ); + } + else + { + if ( storage_path[0] == '/' ) + snprintf( event_data->path, sizeof(event_data->path), "%s/%ld/%ld", storage_path, event_data->monitor_id, event_data->event_id ); + else + snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%ld", staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, event_data->event_id ); + } + event_data->frame_count = dbrow[3] == NULL ? 0 : atoi(dbrow[3]); + event_data->duration = atof(dbrow[5]); + strncpy( event_data->video_file, dbrow[6], sizeof( event_data->video_file )-1 ); + + updateFrameRate( (double)event_data->frame_count/event_data->duration ); + + mysql_free_result( result ); + + snprintf( sql, sizeof(sql), "select FrameId, unix_timestamp( `TimeStamp` ), Delta from Frames where EventId = %d order by FrameId asc", event_id ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + + result = mysql_store_result( &dbconn ); + if ( !result ) + { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + + event_data->n_frames = mysql_num_rows( result ); + + event_data->frames = new FrameData[event_data->frame_count]; + int id, last_id = 0; + time_t timestamp, last_timestamp = event_data->start_time; + double delta, last_delta = 0.0; + while ( ( dbrow = mysql_fetch_row( result ) ) ) + { + id = atoi(dbrow[0]); + timestamp = atoi(dbrow[1]); + delta = atof(dbrow[2]); + int id_diff = id - last_id; + double frame_delta = (delta-last_delta)/id_diff; + if ( id_diff > 1 ) { - if ( storage_path[0] == '/' ) - snprintf( event_data->path, sizeof(event_data->path), "%s/%ld/%ld", storage_path, event_data->monitor_id, event_data->event_id ); - else - snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%ld", staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, event_data->event_id ); + for ( int i = last_id+1; i < id; i++ ) + { + event_data->frames[i-1].timestamp = (time_t)(last_timestamp + ((i-last_id)*frame_delta)); + event_data->frames[i-1].offset = (time_t)(event_data->frames[i-1].timestamp-event_data->start_time); + event_data->frames[i-1].delta = frame_delta; + event_data->frames[i-1].in_db = false; + } } - event_data->frame_count = dbrow[3] == NULL ? 0 : atoi(dbrow[3]); - event_data->duration = atof(dbrow[5]); - strncpy( event_data->video_file, dbrow[6], sizeof( event_data->video_file )-1 ); + event_data->frames[id-1].timestamp = timestamp; + event_data->frames[id-1].offset = (time_t)(event_data->frames[id-1].timestamp-event_data->start_time); + event_data->frames[id-1].delta = id>1?frame_delta:0.0; + event_data->frames[id-1].in_db = true; + last_id = id; + last_delta = delta; + last_timestamp = timestamp; + } + if ( mysql_errno( &dbconn ) ) + { + Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - updateFrameRate( (double)event_data->frame_count/event_data->duration ); + //for ( int i = 0; i < 250; i++ ) + //{ + //Info( "%d -> %d @ %f (%d)", i+1, event_data->frames[i].timestamp, event_data->frames[i].delta, event_data->frames[i].in_db ); + //} - mysql_free_result( result ); + mysql_free_result( result ); - snprintf( sql, sizeof(sql), "select FrameId, unix_timestamp( `TimeStamp` ), Delta from Frames where EventId = %d order by FrameId asc", event_id ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + if ( forceEventChange || mode == MODE_ALL_GAPLESS ) + { + if ( replay_rate > 0 ) + curr_stream_time = event_data->frames[0].timestamp; + else + curr_stream_time = event_data->frames[event_data->frame_count-1].timestamp; + } + Debug( 2, "Event:%ld, Frames:%ld, Duration: %.2f", event_data->event_id, event_data->frame_count, event_data->duration ); - result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - - event_data->n_frames = mysql_num_rows( result ); - - event_data->frames = new FrameData[event_data->frame_count]; - int id, last_id = 0; - time_t timestamp, last_timestamp = event_data->start_time; - double delta, last_delta = 0.0; - while ( ( dbrow = mysql_fetch_row( result ) ) ) - { - id = atoi(dbrow[0]); - timestamp = atoi(dbrow[1]); - delta = atof(dbrow[2]); - int id_diff = id - last_id; - double frame_delta = (delta-last_delta)/id_diff; - if ( id_diff > 1 ) - { - for ( int i = last_id+1; i < id; i++ ) - { - event_data->frames[i-1].timestamp = (time_t)(last_timestamp + ((i-last_id)*frame_delta)); - event_data->frames[i-1].offset = (time_t)(event_data->frames[i-1].timestamp-event_data->start_time); - event_data->frames[i-1].delta = frame_delta; - event_data->frames[i-1].in_db = false; - } - } - event_data->frames[id-1].timestamp = timestamp; - event_data->frames[id-1].offset = (time_t)(event_data->frames[id-1].timestamp-event_data->start_time); - event_data->frames[id-1].delta = id>1?frame_delta:0.0; - event_data->frames[id-1].in_db = true; - last_id = id; - last_delta = delta; - last_timestamp = timestamp; - } - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - - //for ( int i = 0; i < 250; i++ ) - //{ - //Info( "%d -> %d @ %f (%d)", i+1, event_data->frames[i].timestamp, event_data->frames[i].delta, event_data->frames[i].in_db ); - //} - - mysql_free_result( result ); - - if ( forceEventChange || mode == MODE_ALL_GAPLESS ) - { - if ( replay_rate > 0 ) - curr_stream_time = event_data->frames[0].timestamp; - else - curr_stream_time = event_data->frames[event_data->frame_count-1].timestamp; - } - Debug( 2, "Event:%ld, Frames:%ld, Duration: %.2f", event_data->event_id, event_data->frame_count, event_data->duration ); - - return( true ); + return( true ); } void EventStream::processCommand( const CmdMsg *msg ) { - Debug( 2, "Got message, type %d, msg %d", msg->msg_type, msg->msg_data[0] ) + Debug( 2, "Got message, type %d, msg %d", msg->msg_type, msg->msg_data[0] ) // Check for incoming command switch( (MsgCommand)msg->msg_data[0] ) { - case CMD_PAUSE : + case CMD_PAUSE : { - Debug( 1, "Got PAUSE command" ); + Debug( 1, "Got PAUSE command" ); - // Set paused flag - paused = true; - replay_rate = ZM_RATE_BASE; - last_frame_sent = TV_2_FLOAT( now ); - break; + // Set paused flag + paused = true; + replay_rate = ZM_RATE_BASE; + last_frame_sent = TV_2_FLOAT( now ); + break; } - case CMD_PLAY : + case CMD_PLAY : { - Debug( 1, "Got PLAY command" ); - if ( paused ) - { - // Clear paused flag - paused = false; - } - - // If we are in single event mode and at the last frame, replay the current event - if ( (mode == MODE_SINGLE) && ((unsigned int)curr_frame_id == event_data->frame_count) ) - curr_frame_id = 1; - - replay_rate = ZM_RATE_BASE; - break; - } - case CMD_VARPLAY : - { - Debug( 1, "Got VARPLAY command" ); - if ( paused ) - { - // Clear paused flag - paused = false; - } - replay_rate = ntohs(((unsigned char)msg->msg_data[2]<<8)|(unsigned char)msg->msg_data[1])-32768; - break; - } - case CMD_STOP : - { - Debug( 1, "Got STOP command" ); - + Debug( 1, "Got PLAY command" ); + if ( paused ) + { // Clear paused flag paused = false; - break; + } + + // If we are in single event mode and at the last frame, replay the current event + if ( (mode == MODE_SINGLE) && ((unsigned int)curr_frame_id == event_data->frame_count) ) + curr_frame_id = 1; + + replay_rate = ZM_RATE_BASE; + break; } - case CMD_FASTFWD : + case CMD_VARPLAY : { - Debug( 1, "Got FAST FWD command" ); - if ( paused ) - { - // Clear paused flag - paused = false; - } - // Set play rate - switch ( replay_rate ) - { - case 2 * ZM_RATE_BASE : - replay_rate = 5 * ZM_RATE_BASE; - break; - case 5 * ZM_RATE_BASE : - replay_rate = 10 * ZM_RATE_BASE; - break; - case 10 * ZM_RATE_BASE : - replay_rate = 25 * ZM_RATE_BASE; - break; - case 25 * ZM_RATE_BASE : - case 50 * ZM_RATE_BASE : - replay_rate = 50 * ZM_RATE_BASE; - break; - default : - replay_rate = 2 * ZM_RATE_BASE; - break; - } - break; - } - case CMD_SLOWFWD : - { - Debug( 1, "Got SLOW FWD command" ); - // Set paused flag - paused = true; - // Set play rate - replay_rate = ZM_RATE_BASE; - // Set step - step = 1; - break; - } - case CMD_SLOWREV : - { - Debug( 1, "Got SLOW REV command" ); - // Set paused flag - paused = true; - // Set play rate - replay_rate = ZM_RATE_BASE; - // Set step - step = -1; - break; - } - case CMD_FASTREV : - { - Debug( 1, "Got FAST REV command" ); - if ( paused ) - { - // Clear paused flag - paused = false; - } - // Set play rate - switch ( replay_rate ) - { - case -2 * ZM_RATE_BASE : - replay_rate = -5 * ZM_RATE_BASE; - break; - case -5 * ZM_RATE_BASE : - replay_rate = -10 * ZM_RATE_BASE; - break; - case -10 * ZM_RATE_BASE : - replay_rate = -25 * ZM_RATE_BASE; - break; - case -25 * ZM_RATE_BASE : - case -50 * ZM_RATE_BASE : - replay_rate = -50 * ZM_RATE_BASE; - break; - default : - replay_rate = -2 * ZM_RATE_BASE; - break; - } - break; - } - case CMD_ZOOMIN : - { - x = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; - y = ((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; - Debug( 1, "Got ZOOM IN command, to %d,%d", x, y ); - switch ( zoom ) - { - case 100: - zoom = 150; - break; - case 150: - zoom = 200; - break; - case 200: - zoom = 300; - break; - case 300: - zoom = 400; - break; - case 400: - default : - zoom = 500; - break; - } - break; - } - case CMD_ZOOMOUT : - { - Debug( 1, "Got ZOOM OUT command" ); - switch ( zoom ) - { - case 500: - zoom = 400; - break; - case 400: - zoom = 300; - break; - case 300: - zoom = 200; - break; - case 200: - zoom = 150; - break; - case 150: - default : - zoom = 100; - break; - } - break; - } - case CMD_PAN : - { - x = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; - y = ((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; - Debug( 1, "Got PAN command, to %d,%d", x, y ); - break; - } - case CMD_SCALE : - { - scale = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; - Debug( 1, "Got SCALE command, to %d", scale ); - break; - } - case CMD_PREV : - { - Debug( 1, "Got PREV command" ); - if ( replay_rate >= 0 ) - curr_frame_id = 0; - else - curr_frame_id = event_data->frame_count+1; + Debug( 1, "Got VARPLAY command" ); + if ( paused ) + { + // Clear paused flag paused = false; - forceEventChange = true; - break; + } + replay_rate = ntohs(((unsigned char)msg->msg_data[2]<<8)|(unsigned char)msg->msg_data[1])-32768; + break; } - case CMD_NEXT : + case CMD_STOP : { - Debug( 1, "Got NEXT command" ); - if ( replay_rate >= 0 ) - curr_frame_id = event_data->frame_count+1; - else - curr_frame_id = 0; + Debug( 1, "Got STOP command" ); + + // Clear paused flag + paused = false; + break; + } + case CMD_FASTFWD : + { + Debug( 1, "Got FAST FWD command" ); + if ( paused ) + { + // Clear paused flag paused = false; - forceEventChange = true; - break; + } + // Set play rate + switch ( replay_rate ) + { + case 2 * ZM_RATE_BASE : + replay_rate = 5 * ZM_RATE_BASE; + break; + case 5 * ZM_RATE_BASE : + replay_rate = 10 * ZM_RATE_BASE; + break; + case 10 * ZM_RATE_BASE : + replay_rate = 25 * ZM_RATE_BASE; + break; + case 25 * ZM_RATE_BASE : + case 50 * ZM_RATE_BASE : + replay_rate = 50 * ZM_RATE_BASE; + break; + default : + replay_rate = 2 * ZM_RATE_BASE; + break; + } + break; } - case CMD_SEEK : + case CMD_SLOWFWD : { - int offset = ((unsigned char)msg->msg_data[1]<<24)|((unsigned char)msg->msg_data[2]<<16)|((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; - curr_frame_id = (int)(event_data->frame_count*offset/event_data->duration); - Debug( 1, "Got SEEK command, to %d (new cfid: %d)", offset, curr_frame_id ); - break; + Debug( 1, "Got SLOW FWD command" ); + // Set paused flag + paused = true; + // Set play rate + replay_rate = ZM_RATE_BASE; + // Set step + step = 1; + break; } - case CMD_QUERY : + case CMD_SLOWREV : { - Debug( 1, "Got QUERY command, sending STATUS" ); - break; + Debug( 1, "Got SLOW REV command" ); + // Set paused flag + paused = true; + // Set play rate + replay_rate = ZM_RATE_BASE; + // Set step + step = -1; + break; } - case CMD_QUIT : + case CMD_FASTREV : { - Info ("User initiated exit - CMD_QUIT"); - break; + Debug( 1, "Got FAST REV command" ); + if ( paused ) + { + // Clear paused flag + paused = false; + } + // Set play rate + switch ( replay_rate ) + { + case -2 * ZM_RATE_BASE : + replay_rate = -5 * ZM_RATE_BASE; + break; + case -5 * ZM_RATE_BASE : + replay_rate = -10 * ZM_RATE_BASE; + break; + case -10 * ZM_RATE_BASE : + replay_rate = -25 * ZM_RATE_BASE; + break; + case -25 * ZM_RATE_BASE : + case -50 * ZM_RATE_BASE : + replay_rate = -50 * ZM_RATE_BASE; + break; + default : + replay_rate = -2 * ZM_RATE_BASE; + break; + } + break; } - default : + case CMD_ZOOMIN : { - // Do nothing, for now + x = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; + y = ((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; + Debug( 1, "Got ZOOM IN command, to %d,%d", x, y ); + switch ( zoom ) + { + case 100: + zoom = 150; + break; + case 150: + zoom = 200; + break; + case 200: + zoom = 300; + break; + case 300: + zoom = 400; + break; + case 400: + default : + zoom = 500; + break; + } + break; + } + case CMD_ZOOMOUT : + { + Debug( 1, "Got ZOOM OUT command" ); + switch ( zoom ) + { + case 500: + zoom = 400; + break; + case 400: + zoom = 300; + break; + case 300: + zoom = 200; + break; + case 200: + zoom = 150; + break; + case 150: + default : + zoom = 100; + break; + } + break; + } + case CMD_PAN : + { + x = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; + y = ((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; + Debug( 1, "Got PAN command, to %d,%d", x, y ); + break; + } + case CMD_SCALE : + { + scale = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; + Debug( 1, "Got SCALE command, to %d", scale ); + break; + } + case CMD_PREV : + { + Debug( 1, "Got PREV command" ); + if ( replay_rate >= 0 ) + curr_frame_id = 0; + else + curr_frame_id = event_data->frame_count+1; + paused = false; + forceEventChange = true; + break; + } + case CMD_NEXT : + { + Debug( 1, "Got NEXT command" ); + if ( replay_rate >= 0 ) + curr_frame_id = event_data->frame_count+1; + else + curr_frame_id = 0; + paused = false; + forceEventChange = true; + break; + } + case CMD_SEEK : + { + int offset = ((unsigned char)msg->msg_data[1]<<24)|((unsigned char)msg->msg_data[2]<<16)|((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; + curr_frame_id = (int)(event_data->frame_count*offset/event_data->duration); + Debug( 1, "Got SEEK command, to %d (new cfid: %d)", offset, curr_frame_id ); + break; + } + case CMD_QUERY : + { + Debug( 1, "Got QUERY command, sending STATUS" ); + break; + } + case CMD_QUIT : + { + Info ("User initiated exit - CMD_QUIT"); + break; + } + default : + { + // Do nothing, for now } } - struct { - int event; - int progress; - int rate; - int zoom; - bool paused; - } status_data; + struct { + int event; + int progress; + int rate; + int zoom; + bool paused; + } status_data; - status_data.event = event_data->event_id; - status_data.progress = (int)event_data->frames[curr_frame_id-1].offset; - status_data.rate = replay_rate; - status_data.zoom = zoom; - status_data.paused = paused; - Debug( 2, "E:%d, P:%d, p:%d R:%d, Z:%d", - status_data.event, - status_data.paused, - status_data.progress, - status_data.rate, - status_data.zoom - ); + status_data.event = event_data->event_id; + status_data.progress = (int)event_data->frames[curr_frame_id-1].offset; + status_data.rate = replay_rate; + status_data.zoom = zoom; + status_data.paused = paused; + Debug( 2, "E:%d, P:%d, p:%d R:%d, Z:%d", + status_data.event, + status_data.paused, + status_data.progress, + status_data.rate, + status_data.zoom + ); - DataMsg status_msg; - status_msg.msg_type = MSG_DATA_EVENT; - memcpy( &status_msg.msg_data, &status_data, sizeof(status_data) ); - if ( sendto( sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr) ) < 0 ) + DataMsg status_msg; + status_msg.msg_type = MSG_DATA_EVENT; + memcpy( &status_msg.msg_data, &status_data, sizeof(status_data) ); + if ( sendto( sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr) ) < 0 ) + { + //if ( errno != EAGAIN ) { - //if ( errno != EAGAIN ) - { - Error( "Can't sendto on sd %d: %s", sd, strerror(errno) ); - exit( -1 ); - } + Error( "Can't sendto on sd %d: %s", sd, strerror(errno) ); + exit( -1 ); } - // quit after sending a status, if this was a quit request - if ((MsgCommand)msg->msg_data[0]==CMD_QUIT) - exit(0); + } + // quit after sending a status, if this was a quit request + if ((MsgCommand)msg->msg_data[0]==CMD_QUIT) + exit(0); - updateFrameRate( (double)event_data->frame_count/event_data->duration ); + updateFrameRate( (double)event_data->frame_count/event_data->duration ); } void EventStream::checkEventLoaded() { - bool reload_event = false; - static char sql[ZM_SQL_SML_BUFSIZ]; + bool reload_event = false; + static char sql[ZM_SQL_SML_BUFSIZ]; - if ( curr_frame_id <= 0 ) + if ( curr_frame_id <= 0 ) + { + snprintf( sql, sizeof(sql), "select Id from Events where MonitorId = %ld and Id < %ld order by Id desc limit 1", event_data->monitor_id, event_data->event_id ); + reload_event = true; + } + else if ( (unsigned int)curr_frame_id > event_data->frame_count ) + { + snprintf( sql, sizeof(sql), "select Id from Events where MonitorId = %ld and Id > %ld order by Id asc limit 1", event_data->monitor_id, event_data->event_id ); + reload_event = true; + } + + if ( reload_event ) + { + if ( forceEventChange || mode != MODE_SINGLE ) { - snprintf( sql, sizeof(sql), "select Id from Events where MonitorId = %ld and Id < %ld order by Id desc limit 1", event_data->monitor_id, event_data->event_id ); - reload_event = true; - } - else if ( (unsigned int)curr_frame_id > event_data->frame_count ) - { - snprintf( sql, sizeof(sql), "select Id from Events where MonitorId = %ld and Id > %ld order by Id asc limit 1", event_data->monitor_id, event_data->event_id ); - reload_event = true; - } + //Info( "SQL:%s", sql ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - if ( reload_event ) - { - if ( forceEventChange || mode != MODE_SINGLE ) - { - //Info( "SQL:%s", sql ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) + { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + MYSQL_ROW dbrow = mysql_fetch_row( result ); - MYSQL_RES *result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - MYSQL_ROW dbrow = mysql_fetch_row( result ); + if ( mysql_errno( &dbconn ) ) + { + Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + if ( dbrow ) + { + int event_id = atoi(dbrow[0]); + Debug( 1, "Loading new event %d", event_id ); - if ( dbrow ) - { - int event_id = atoi(dbrow[0]); - Debug( 1, "Loading new event %d", event_id ); + loadEventData( event_id ); - loadEventData( event_id ); - - Debug( 2, "Current frame id = %d", curr_frame_id ); - if ( replay_rate < 0 ) - curr_frame_id = event_data->frame_count; - else - curr_frame_id = 1; - Debug( 2, "New frame id = %d", curr_frame_id ); - } - else - { - if ( curr_frame_id <= 0 ) - curr_frame_id = 1; - else - curr_frame_id = event_data->frame_count; - paused = true; - } - mysql_free_result( result ); - forceEventChange = false; - } + Debug( 2, "Current frame id = %d", curr_frame_id ); + if ( replay_rate < 0 ) + curr_frame_id = event_data->frame_count; else - { - if ( curr_frame_id <= 0 ) - curr_frame_id = 1; - else - curr_frame_id = event_data->frame_count; - paused = true; - } + curr_frame_id = 1; + Debug( 2, "New frame id = %d", curr_frame_id ); + } + else + { + if ( curr_frame_id <= 0 ) + curr_frame_id = 1; + else + curr_frame_id = event_data->frame_count; + paused = true; + } + mysql_free_result( result ); + forceEventChange = false; } + else + { + if ( curr_frame_id <= 0 ) + curr_frame_id = 1; + else + curr_frame_id = event_data->frame_count; + paused = true; + } + } } Image * EventStream::getImage( ) { - Event::Initialise(); - static char filepath[PATH_MAX]; - - Debug( 2, "EventStream::getImage path(%s) frame(%d)", event_data->path, curr_frame_id ); - snprintf( filepath, sizeof(filepath), Event::capture_file_format, event_data->path, curr_frame_id ); - Debug( 2, "EventStream::getImage path(%s) ", filepath, curr_frame_id ); - Image *image = new Image( filepath ); - return image; + Event::Initialise(); + static char filepath[PATH_MAX]; + + Debug( 2, "EventStream::getImage path(%s) frame(%d)", event_data->path, curr_frame_id ); + snprintf( filepath, sizeof(filepath), Event::capture_file_format, event_data->path, curr_frame_id ); + Debug( 2, "EventStream::getImage path(%s) ", filepath, curr_frame_id ); + Image *image = new Image( filepath ); + return image; } bool EventStream::sendFrame( int delta_us ) { - Debug( 2, "Sending frame %d", curr_frame_id ); + Debug( 2, "Sending frame %d", curr_frame_id ); - static char filepath[PATH_MAX]; - static struct stat filestat; - FILE *fdj = NULL; - - snprintf( filepath, sizeof(filepath), Event::capture_file_format, event_data->path, curr_frame_id ); + static char filepath[PATH_MAX]; + static struct stat filestat; + FILE *fdj = NULL; + + snprintf( filepath, sizeof(filepath), Event::capture_file_format, event_data->path, curr_frame_id ); #if HAVE_LIBAVCODEC - if ( type == STREAM_MPEG ) + if ( type == STREAM_MPEG ) + { + Image image( filepath ); + + Image *send_image = prepareImage( &image ); + + if ( !vid_stream ) { - Image image( filepath ); + vid_stream = new VideoStream( "pipe:", format, bitrate, effective_fps, send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height() ); + fprintf( stdout, "Content-type: %s\r\n\r\n", vid_stream->MimeType() ); + vid_stream->OpenStream(); + } + /* double pts = */ vid_stream->EncodeFrame( send_image->Buffer(), send_image->Size(), config.mpeg_timed_frames, delta_us*1000 ); + } + else +#endif // HAVE_LIBAVCODEC + { + static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; - Image *send_image = prepareImage( &image ); + int img_buffer_size = 0; + uint8_t *img_buffer = temp_img_buffer; - if ( !vid_stream ) - { - vid_stream = new VideoStream( "pipe:", format, bitrate, effective_fps, send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height() ); - fprintf( stdout, "Content-type: %s\r\n\r\n", vid_stream->MimeType() ); - vid_stream->OpenStream(); - } - /* double pts = */ vid_stream->EncodeFrame( send_image->Buffer(), send_image->Size(), config.mpeg_timed_frames, delta_us*1000 ); + bool send_raw = ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)); + + fprintf( stdout, "--ZoneMinderFrame\r\n" ); + + if ( type != STREAM_JPEG ) + send_raw = false; + + if ( send_raw ) + { + fdj = fopen( filepath, "rb" ); + if ( !fdj ) + { + Error( "Can't open %s: %s", filepath, strerror(errno) ); + return( false ); + } +#if HAVE_SENDFILE + if( fstat(fileno(fdj),&filestat) < 0 ) { + Error( "Failed getting information about file %s: %s", filepath, strerror(errno) ); + return( false ); + } +#else + img_buffer_size = fread( img_buffer, 1, sizeof(temp_img_buffer), fdj ); +#endif } else -#endif // HAVE_LIBAVCODEC { - static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; + Image image( filepath ); - int img_buffer_size = 0; - uint8_t *img_buffer = temp_img_buffer; + Image *send_image = prepareImage( &image ); - bool send_raw = ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)); - - fprintf( stdout, "--ZoneMinderFrame\r\n" ); - - if ( type != STREAM_JPEG ) - send_raw = false; - - if ( send_raw ) - { - fdj = fopen( filepath, "rb" ); - if ( !fdj ) - { - Error( "Can't open %s: %s", filepath, strerror(errno) ); - return( false ); - } -#if HAVE_SENDFILE - if( fstat(fileno(fdj),&filestat) < 0 ) { - Error( "Failed getting information about file %s: %s", filepath, strerror(errno) ); - return( false ); - } -#else - img_buffer_size = fread( img_buffer, 1, sizeof(temp_img_buffer), fdj ); -#endif - } - else - { - Image image( filepath ); - - Image *send_image = prepareImage( &image ); - - switch( type ) - { - case STREAM_JPEG : - send_image->EncodeJpeg( img_buffer, &img_buffer_size ); - break; - case STREAM_ZIP : + switch( type ) + { + case STREAM_JPEG : + send_image->EncodeJpeg( img_buffer, &img_buffer_size ); + break; + case STREAM_ZIP : #if HAVE_ZLIB_H - unsigned long zip_buffer_size; - send_image->Zip( img_buffer, &zip_buffer_size ); - img_buffer_size = zip_buffer_size; - break; + unsigned long zip_buffer_size; + send_image->Zip( img_buffer, &zip_buffer_size ); + img_buffer_size = zip_buffer_size; + break; #else - Error("zlib is required for zipped images. Falling back to raw image"); - type = STREAM_RAW; + Error("zlib is required for zipped images. Falling back to raw image"); + type = STREAM_RAW; #endif // HAVE_ZLIB_H - case STREAM_RAW : - img_buffer = (uint8_t*)(send_image->Buffer()); - img_buffer_size = send_image->Size(); - break; - default: - Fatal( "Unexpected frame type %d", type ); - break; - } - } - - switch( type ) - { - case STREAM_JPEG : - fprintf( stdout, "Content-Type: image/jpeg\r\n" ); - break; - case STREAM_RAW : - fprintf( stdout, "Content-Type: image/x-rgb\r\n" ); - break; - case STREAM_ZIP : - fprintf( stdout, "Content-Type: image/x-rgbz\r\n" ); - break; - default : - Fatal( "Unexpected frame type %d", type ); - break; - } - - - if(send_raw) { -#if HAVE_SENDFILE - fprintf( stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size ); - if(zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size) { - /* sendfile() failed, use standard way instead */ - img_buffer_size = fread( img_buffer, 1, sizeof(temp_img_buffer), fdj ); - if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) { - Error("Unable to send raw frame %u: %s",curr_frame_id,strerror(errno)); - return( false ); - } - } -#else - fprintf( stdout, "Content-Length: %d\r\n\r\n", img_buffer_size ); - if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) { - Error("Unable to send raw frame %u: %s",curr_frame_id,strerror(errno)); - return( false ); - } -#endif - fclose(fdj); /* Close the file handle */ - } else { - fprintf( stdout, "Content-Length: %d\r\n\r\n", img_buffer_size ); - if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) - { - Error( "Unable to send stream frame: %s", strerror(errno) ); - return( false ); - } - } - - fprintf( stdout, "\r\n\r\n" ); - fflush( stdout ); + case STREAM_RAW : + img_buffer = (uint8_t*)(send_image->Buffer()); + img_buffer_size = send_image->Size(); + break; + default: + Fatal( "Unexpected frame type %d", type ); + break; + } } - last_frame_sent = TV_2_FLOAT( now ); - return( true ); + + switch( type ) + { + case STREAM_JPEG : + fprintf( stdout, "Content-Type: image/jpeg\r\n" ); + break; + case STREAM_RAW : + fprintf( stdout, "Content-Type: image/x-rgb\r\n" ); + break; + case STREAM_ZIP : + fprintf( stdout, "Content-Type: image/x-rgbz\r\n" ); + break; + default : + Fatal( "Unexpected frame type %d", type ); + break; + } + + + if(send_raw) { +#if HAVE_SENDFILE + fprintf( stdout, "Content-Length: %d\r\n\r\n", (int)filestat.st_size ); + if(zm_sendfile(fileno(stdout), fileno(fdj), 0, (int)filestat.st_size) != (int)filestat.st_size) { + /* sendfile() failed, use standard way instead */ + img_buffer_size = fread( img_buffer, 1, sizeof(temp_img_buffer), fdj ); + if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) { + Error("Unable to send raw frame %u: %s",curr_frame_id,strerror(errno)); + return( false ); + } + } +#else + fprintf( stdout, "Content-Length: %d\r\n\r\n", img_buffer_size ); + if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) { + Error("Unable to send raw frame %u: %s",curr_frame_id,strerror(errno)); + return( false ); + } +#endif + fclose(fdj); /* Close the file handle */ + } else { + fprintf( stdout, "Content-Length: %d\r\n\r\n", img_buffer_size ); + if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) + { + Error( "Unable to send stream frame: %s", strerror(errno) ); + return( false ); + } + } + + fprintf( stdout, "\r\n\r\n" ); + fflush( stdout ); + } + last_frame_sent = TV_2_FLOAT( now ); + return( true ); } void EventStream::runStream() { - Event::Initialise(); + Event::Initialise(); - openComms(); + openComms(); - checkInitialised(); + checkInitialised(); - updateFrameRate( (double)event_data->frame_count/event_data->duration ); + updateFrameRate( (double)event_data->frame_count/event_data->duration ); - if ( type == STREAM_JPEG ) - fprintf( stdout, "Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame\r\n\r\n" ); + if ( type == STREAM_JPEG ) + fprintf( stdout, "Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame\r\n\r\n" ); - if ( !event_data ) + if ( !event_data ) + { + sendTextFrame( "No event data found" ); + exit( 0 ); + } + + unsigned int delta_us = 0; + while( !zm_terminate ) + { + gettimeofday( &now, NULL ); + + while(checkCommandQueue()); + + if ( step != 0 ) + curr_frame_id += step; + + checkEventLoaded(); + + // Get current frame data + FrameData *frame_data = &event_data->frames[curr_frame_id-1]; + + //Info( "cst:%.2f", curr_stream_time ); + //Info( "cfid:%d", curr_frame_id ); + //Info( "fdt:%d", frame_data->timestamp ); + if ( !paused ) { - sendTextFrame( "No event data found" ); - exit( 0 ); + bool in_event = true; + double time_to_event = 0; + if ( replay_rate > 0 ) + { + time_to_event = event_data->frames[0].timestamp - curr_stream_time; + if ( time_to_event > 0 ) + in_event = false; + } + else if ( replay_rate < 0 ) + { + time_to_event = curr_stream_time - event_data->frames[event_data->frame_count-1].timestamp; + if ( time_to_event > 0 ) + in_event = false; + } + if ( !in_event ) + { + double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent; + if ( actual_delta_time > 1 ) + { + static char frame_text[64]; + snprintf( frame_text, sizeof(frame_text), "Time to next event = %d seconds", (int)time_to_event ); + if ( !sendTextFrame( frame_text ) ) + zm_terminate = true; + } + //else + //{ + usleep( STREAM_PAUSE_WAIT ); + //curr_stream_time += (replay_rate>0?1:-1) * ((1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000)); + curr_stream_time += (1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000); + //} + continue; + } } - unsigned int delta_us = 0; - while( !zm_terminate ) + // Figure out if we should send this frame + bool send_frame = false; + if ( !paused ) { - gettimeofday( &now, NULL ); - - while(checkCommandQueue()); - - if ( step != 0 ) - curr_frame_id += step; - - checkEventLoaded(); - - // Get current frame data - FrameData *frame_data = &event_data->frames[curr_frame_id-1]; - - //Info( "cst:%.2f", curr_stream_time ); - //Info( "cfid:%d", curr_frame_id ); - //Info( "fdt:%d", frame_data->timestamp ); - if ( !paused ) - { - bool in_event = true; - double time_to_event = 0; - if ( replay_rate > 0 ) - { - time_to_event = event_data->frames[0].timestamp - curr_stream_time; - if ( time_to_event > 0 ) - in_event = false; - } - else if ( replay_rate < 0 ) - { - time_to_event = curr_stream_time - event_data->frames[event_data->frame_count-1].timestamp; - if ( time_to_event > 0 ) - in_event = false; - } - if ( !in_event ) - { - double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent; - if ( actual_delta_time > 1 ) - { - static char frame_text[64]; - snprintf( frame_text, sizeof(frame_text), "Time to next event = %d seconds", (int)time_to_event ); - if ( !sendTextFrame( frame_text ) ) - zm_terminate = true; - } - //else - //{ - usleep( STREAM_PAUSE_WAIT ); - //curr_stream_time += (replay_rate>0?1:-1) * ((1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000)); - curr_stream_time += (1.0L * replay_rate * STREAM_PAUSE_WAIT)/(ZM_RATE_BASE * 1000000); - //} - continue; - } - } - - // Figure out if we should send this frame - bool send_frame = false; - if ( !paused ) - { - // If we are streaming and this frame is due to be sent - if ( ((curr_frame_id-1)%frame_mod) == 0 ) - { - delta_us = (unsigned int)(frame_data->delta * 1000000); - // if effective > base we should speed up frame delivery - delta_us = (unsigned int)((delta_us * base_fps)/effective_fps); - // but must not exceed maxfps - delta_us = max(delta_us, 1000000 / maxfps); - send_frame = true; - } - } - else if ( step != 0 ) - { - // We are paused and are just stepping forward or backward one frame - step = 0; - send_frame = true; - } - else - { - // We are paused, and doing nothing - double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent; - if ( actual_delta_time > MAX_STREAM_DELAY ) - { - // Send keepalive - Debug( 2, "Sending keepalive frame" ); - send_frame = true; - } - } - - if ( send_frame ) - if ( !sendFrame( delta_us ) ) - zm_terminate = true; - - curr_stream_time = frame_data->timestamp; - - if ( !paused ) - { - curr_frame_id += replay_rate>0?1:-1; - if ( send_frame && type != STREAM_MPEG ) - { - Debug( 3, "dUs: %d", delta_us ); - usleep( delta_us ); - } - } - else - { - usleep( (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2))) ); - } + // If we are streaming and this frame is due to be sent + if ( ((curr_frame_id-1)%frame_mod) == 0 ) + { + delta_us = (unsigned int)(frame_data->delta * 1000000); + // if effective > base we should speed up frame delivery + delta_us = (unsigned int)((delta_us * base_fps)/effective_fps); + // but must not exceed maxfps + delta_us = max(delta_us, 1000000 / maxfps); + send_frame = true; + } } + else if ( step != 0 ) + { + // We are paused and are just stepping forward or backward one frame + step = 0; + send_frame = true; + } + else + { + // We are paused, and doing nothing + double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent; + if ( actual_delta_time > MAX_STREAM_DELAY ) + { + // Send keepalive + Debug( 2, "Sending keepalive frame" ); + send_frame = true; + } + } + + if ( send_frame ) + if ( !sendFrame( delta_us ) ) + zm_terminate = true; + + curr_stream_time = frame_data->timestamp; + + if ( !paused ) + { + curr_frame_id += replay_rate>0?1:-1; + if ( send_frame && type != STREAM_MPEG ) + { + Debug( 3, "dUs: %d", delta_us ); + usleep( delta_us ); + } + } + else + { + usleep( (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2))) ); + } + } #if HAVE_LIBAVCODEC - if ( type == STREAM_MPEG ) - delete vid_stream; + if ( type == STREAM_MPEG ) + delete vid_stream; #endif // HAVE_LIBAVCODEC - closeComms(); + closeComms(); } diff --git a/src/zm_event.h b/src/zm_event.h index 93df93c68..576e0e869 100644 --- a/src/zm_event.h +++ b/src/zm_event.h @@ -42,246 +42,246 @@ class Zone; class Monitor; -#define MAX_PRE_ALARM_FRAMES 16 // Maximum number of prealarm frames that can be stored +#define MAX_PRE_ALARM_FRAMES 16 // Maximum number of prealarm frames that can be stored // // Class describing events, i.e. captured periods of activity. // class Event { -friend class EventStream; + friend class EventStream; -protected: - static bool initialised; - static char capture_file_format[PATH_MAX]; - static char analyse_file_format[PATH_MAX]; - static char general_file_format[PATH_MAX]; - static char video_file_format[PATH_MAX]; + protected: + static bool initialised; + static char capture_file_format[PATH_MAX]; + static char analyse_file_format[PATH_MAX]; + static char general_file_format[PATH_MAX]; + static char video_file_format[PATH_MAX]; -protected: - static int sd; + protected: + static int sd; -public: - typedef std::set StringSet; - typedef std::map StringSetMap; + public: + typedef std::set StringSet; + typedef std::map StringSetMap; -protected: - typedef enum { NORMAL, BULK, ALARM } FrameType; + protected: + typedef enum { NORMAL, BULK, ALARM } FrameType; - struct PreAlarmData - { - Image *image; - struct timeval timestamp; - unsigned int score; - Image *alarm_frame; - }; + struct PreAlarmData + { + Image *image; + struct timeval timestamp; + unsigned int score; + Image *alarm_frame; + }; - static int pre_alarm_count; - static PreAlarmData pre_alarm_data[MAX_PRE_ALARM_FRAMES]; + static int pre_alarm_count; + static PreAlarmData pre_alarm_data[MAX_PRE_ALARM_FRAMES]; -protected: - unsigned int id; - Monitor *monitor; - struct timeval start_time; - struct timeval end_time; - std::string cause; - StringSetMap noteSetMap; - bool videoEvent; - int frames; - int alarm_frames; - unsigned int tot_score; - unsigned int max_score; - char path[PATH_MAX]; - VideoWriter* videowriter; - FILE* timecodes_fd; - char video_name[PATH_MAX]; - char video_file[PATH_MAX]; - char timecodes_name[PATH_MAX]; - char timecodes_file[PATH_MAX]; + protected: + unsigned int id; + Monitor *monitor; + struct timeval start_time; + struct timeval end_time; + std::string cause; + StringSetMap noteSetMap; + bool videoEvent; + int frames; + int alarm_frames; + unsigned int tot_score; + unsigned int max_score; + char path[PATH_MAX]; + VideoWriter* videowriter; + FILE* timecodes_fd; + char video_name[PATH_MAX]; + char video_file[PATH_MAX]; + char timecodes_name[PATH_MAX]; + char timecodes_file[PATH_MAX]; -protected: - int last_db_frame; + protected: + int last_db_frame; -protected: - static void Initialise() - { - if ( initialised ) - return; + protected: + static void Initialise() + { + if ( initialised ) + return; - snprintf( capture_file_format, sizeof(capture_file_format), "%%s/%%0%dd-capture.jpg", config.event_image_digits ); - snprintf( analyse_file_format, sizeof(analyse_file_format), "%%s/%%0%dd-analyse.jpg", config.event_image_digits ); - snprintf( general_file_format, sizeof(general_file_format), "%%s/%%0%dd-%%s", config.event_image_digits ); - snprintf( video_file_format, sizeof(video_file_format), "%%s/%%s"); + snprintf( capture_file_format, sizeof(capture_file_format), "%%s/%%0%dd-capture.jpg", config.event_image_digits ); + snprintf( analyse_file_format, sizeof(analyse_file_format), "%%s/%%0%dd-analyse.jpg", config.event_image_digits ); + snprintf( general_file_format, sizeof(general_file_format), "%%s/%%0%dd-%%s", config.event_image_digits ); + snprintf( video_file_format, sizeof(video_file_format), "%%s/%%s"); - initialised = true; - } + initialised = true; + } - void createNotes( std::string ¬es ); + void createNotes( std::string ¬es ); -public: - static bool OpenFrameSocket( int ); - static bool ValidateFrameSocket( int ); + public: + static bool OpenFrameSocket( int ); + static bool ValidateFrameSocket( int ); -public: - Event( Monitor *p_monitor, struct timeval p_start_time, const std::string &p_cause, const StringSetMap &p_noteSetMap, bool p_videoEvent=false ); - ~Event(); + public: + Event( Monitor *p_monitor, struct timeval p_start_time, const std::string &p_cause, const StringSetMap &p_noteSetMap, bool p_videoEvent=false ); + ~Event(); - int Id() const { return( id ); } - const std::string &Cause() { return( cause ); } - int Frames() const { return( frames ); } - int AlarmFrames() const { return( alarm_frames ); } + int Id() const { return( id ); } + const std::string &Cause() { return( cause ); } + int Frames() const { return( frames ); } + int AlarmFrames() const { return( alarm_frames ); } - const struct timeval &StartTime() const { return( start_time ); } - const struct timeval &EndTime() const { return( end_time ); } - struct timeval &EndTime() { return( end_time ); } + const struct timeval &StartTime() const { return( start_time ); } + const struct timeval &EndTime() const { return( end_time ); } + struct timeval &EndTime() { return( end_time ); } - bool SendFrameImage( const Image *image, bool alarm_frame=false ); - bool WriteFrameImage( Image *image, struct timeval timestamp, const char *event_file, bool alarm_frame=false ); - bool WriteFrameVideo( const Image *image, const struct timeval timestamp, VideoWriter* videow ); + bool SendFrameImage( const Image *image, bool alarm_frame=false ); + bool WriteFrameImage( Image *image, struct timeval timestamp, const char *event_file, bool alarm_frame=false ); + bool WriteFrameVideo( const Image *image, const struct timeval timestamp, VideoWriter* videow ); - void updateNotes( const StringSetMap &stringSetMap ); + void updateNotes( const StringSetMap &stringSetMap ); - void AddFrames( int n_frames, Image **images, struct timeval **timestamps ); - void AddFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL ); + void AddFrames( int n_frames, Image **images, struct timeval **timestamps ); + void AddFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL ); -private: - void AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps ); + private: + void AddFramesInternal( int n_frames, int start_frame, Image **images, struct timeval **timestamps ); -public: - static const char *getSubPath( struct tm *time ) + public: + static const char *getSubPath( struct tm *time ) + { + static char subpath[PATH_MAX] = ""; + snprintf( subpath, sizeof(subpath), "%02d/%02d/%02d/%02d/%02d/%02d", time->tm_year-100, time->tm_mon+1, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec ); + return( subpath ); + } + static const char *getSubPath( time_t *time ) + { + return( Event::getSubPath( localtime( time ) ) ); + } + + char* getEventFile(void){ + return video_file; + } + + public: + static int PreAlarmCount() + { + return( pre_alarm_count ); + } + static void EmptyPreAlarmFrames() + { + if ( pre_alarm_count > 0 ) { - static char subpath[PATH_MAX] = ""; - snprintf( subpath, sizeof(subpath), "%02d/%02d/%02d/%02d/%02d/%02d", time->tm_year-100, time->tm_mon+1, time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec ); - return( subpath ); + for ( int i = 0; i < MAX_PRE_ALARM_FRAMES; i++ ) + { + delete pre_alarm_data[i].image; + delete pre_alarm_data[i].alarm_frame; + } + memset( pre_alarm_data, 0, sizeof(pre_alarm_data) ); } - static const char *getSubPath( time_t *time ) + pre_alarm_count = 0; + } + static void AddPreAlarmFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL ) + { + pre_alarm_data[pre_alarm_count].image = new Image( *image ); + pre_alarm_data[pre_alarm_count].timestamp = timestamp; + pre_alarm_data[pre_alarm_count].score = score; + if ( alarm_frame ) { - return( Event::getSubPath( localtime( time ) ) ); + pre_alarm_data[pre_alarm_count].alarm_frame = new Image( *alarm_frame ); } - - char* getEventFile(void){ - return video_file; + pre_alarm_count++; + } + void SavePreAlarmFrames() + { + for ( int i = 0; i < pre_alarm_count; i++ ) + { + AddFrame( pre_alarm_data[i].image, pre_alarm_data[i].timestamp, pre_alarm_data[i].score, pre_alarm_data[i].alarm_frame ); } - -public: - static int PreAlarmCount() - { - return( pre_alarm_count ); - } - static void EmptyPreAlarmFrames() - { - if ( pre_alarm_count > 0 ) - { - for ( int i = 0; i < MAX_PRE_ALARM_FRAMES; i++ ) - { - delete pre_alarm_data[i].image; - delete pre_alarm_data[i].alarm_frame; - } - memset( pre_alarm_data, 0, sizeof(pre_alarm_data) ); - } - pre_alarm_count = 0; - } - static void AddPreAlarmFrame( Image *image, struct timeval timestamp, int score=0, Image *alarm_frame=NULL ) - { - pre_alarm_data[pre_alarm_count].image = new Image( *image ); - pre_alarm_data[pre_alarm_count].timestamp = timestamp; - pre_alarm_data[pre_alarm_count].score = score; - if ( alarm_frame ) - { - pre_alarm_data[pre_alarm_count].alarm_frame = new Image( *alarm_frame ); - } - pre_alarm_count++; - } - void SavePreAlarmFrames() - { - for ( int i = 0; i < pre_alarm_count; i++ ) - { - AddFrame( pre_alarm_data[i].image, pre_alarm_data[i].timestamp, pre_alarm_data[i].score, pre_alarm_data[i].alarm_frame ); - } - EmptyPreAlarmFrames(); - } + EmptyPreAlarmFrames(); + } }; class EventStream : public StreamBase { -public: + public: typedef enum { MODE_SINGLE, MODE_ALL, MODE_ALL_GAPLESS } StreamMode; -protected: + protected: struct FrameData { - //unsigned long id; - time_t timestamp; - time_t offset; - double delta; - bool in_db; + //unsigned long id; + time_t timestamp; + time_t offset; + double delta; + bool in_db; }; struct EventData { - unsigned long event_id; - unsigned long monitor_id; - unsigned long storage_id; - unsigned long frame_count; - time_t start_time; - double duration; - char path[PATH_MAX]; - int n_frames; - FrameData *frames; - char video_file[PATH_MAX]; + unsigned long event_id; + unsigned long monitor_id; + unsigned long storage_id; + unsigned long frame_count; + time_t start_time; + double duration; + char path[PATH_MAX]; + int n_frames; + FrameData *frames; + char video_file[PATH_MAX]; }; -protected: + protected: static const int STREAM_PAUSE_WAIT = 250000; // Microseconds static const StreamMode DEFAULT_MODE = MODE_SINGLE; -protected: + protected: StreamMode mode; bool forceEventChange; -protected: + protected: int curr_frame_id; double curr_stream_time; EventData *event_data; -protected: + protected: bool loadEventData( int event_id ); - bool loadInitialEventData( int init_event_id, int init_frame_id ); + bool loadInitialEventData( int init_event_id, unsigned int init_frame_id ); bool loadInitialEventData( int monitor_id, time_t event_time ); void checkEventLoaded(); void processCommand( const CmdMsg *msg ); bool sendFrame( int delta_us ); -public: + public: EventStream() { - mode = DEFAULT_MODE; + mode = DEFAULT_MODE; - forceEventChange = false; + forceEventChange = false; - curr_frame_id = 0; - curr_stream_time = 0.0; + curr_frame_id = 0; + curr_stream_time = 0.0; - event_data = 0; + event_data = 0; } - void setStreamStart( int init_event_id, int init_frame_id=0 ) + void setStreamStart( int init_event_id, unsigned int init_frame_id=0 ) { - loadInitialEventData( init_event_id, init_frame_id ); - loadMonitor( event_data->monitor_id ); + loadInitialEventData( init_event_id, init_frame_id ); + loadMonitor( event_data->monitor_id ); } - void setStreamStart( int monitor_id, time_t event_time ) + void setStreamStart( int monitor_id, time_t event_time ) { - loadInitialEventData( monitor_id, event_time ); - loadMonitor( monitor_id ); + loadInitialEventData( monitor_id, event_time ); + loadMonitor( monitor_id ); } void setStreamMode( StreamMode p_mode ) { - mode = p_mode; + mode = p_mode; } void runStream(); - Image *getImage(); + Image *getImage(); }; #endif // ZM_EVENT_H diff --git a/src/zm_exception.h b/src/zm_exception.h index 4af60bfa6..a503be7c9 100644 --- a/src/zm_exception.h +++ b/src/zm_exception.h @@ -27,42 +27,42 @@ class Exception { protected: - typedef enum { INFO, WARNING, ERROR, FATAL } Severity; + typedef enum { INFO, WARNING, ERROR, FATAL } Severity; protected: - std::string mMessage; - Severity mSeverity; + std::string mMessage; + Severity mSeverity; public: - Exception( const std::string &message, Severity severity=ERROR ) : mMessage( message ), mSeverity( severity ) - { - } + Exception( const std::string &message, Severity severity=ERROR ) : mMessage( message ), mSeverity( severity ) + { + } public: - const std::string &getMessage() const - { - return( mMessage ); - } - Severity getSeverity() const - { - return( mSeverity ); - } - bool isInfo() const - { - return( mSeverity == INFO ); - } - bool isWarning() const - { - return( mSeverity == WARNING ); - } - bool isError() const - { - return( mSeverity == ERROR ); - } - bool isFatal() const - { - return( mSeverity == FATAL ); - } + const std::string &getMessage() const + { + return( mMessage ); + } + Severity getSeverity() const + { + return( mSeverity ); + } + bool isInfo() const + { + return( mSeverity == INFO ); + } + bool isWarning() const + { + return( mSeverity == WARNING ); + } + bool isError() const + { + return( mSeverity == ERROR ); + } + bool isFatal() const + { + return( mSeverity == FATAL ); + } }; #endif // ZM_EXCEPTION_H diff --git a/src/zm_ffmpeg.cpp b/src/zm_ffmpeg.cpp index 281009703..fdf35e862 100644 --- a/src/zm_ffmpeg.cpp +++ b/src/zm_ffmpeg.cpp @@ -167,12 +167,21 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint #endif /* Check the buffer sizes */ - size_t insize = avpicture_get_size(in_pf, width, height); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + size_t insize = av_image_get_buffer_size(in_pf, width, height,1); +#else + size_t insize = avpicture_get_size(in_pf, width, height); +#endif if(insize != in_buffer_size) { Error("The input buffer size does not match the expected size for the input format. Required: %d Available: %d", insize, in_buffer_size); return -4; } - size_t outsize = avpicture_get_size(out_pf, width, height); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + size_t outsize = av_image_get_buffer_size(out_pf, width, height,1); +#else + size_t outsize = avpicture_get_size(out_pf, width, height); +#endif + if(outsize < out_buffer_size) { Error("The output buffer is undersized for the output format. Required: %d Available: %d", outsize, out_buffer_size); return -5; @@ -186,13 +195,29 @@ int SWScale::Convert(const uint8_t* in_buffer, const size_t in_buffer_size, uint } /* Fill in the buffers */ - if(!avpicture_fill( (AVPicture*)input_avframe, (uint8_t*)in_buffer, in_pf, width, height ) ) { - Error("Failed filling input frame with input buffer"); - return -7; +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + if(av_image_fill_arrays(input_avframe->data, input_avframe->linesize, + (uint8_t*)in_buffer, in_pf, width, height, 1) <= 0) + { +#else + if(avpicture_fill( (AVPicture*)input_avframe, (uint8_t*)in_buffer, + in_pf, width, height ) <= 0) + { +#endif + Error("Failed filling input frame with input buffer"); + return -7; } - if(!avpicture_fill( (AVPicture*)output_avframe, out_buffer, out_pf, width, height ) ) { - Error("Failed filling output frame with output buffer"); - return -8; +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + if(av_image_fill_arrays(output_avframe->data, output_avframe->linesize, + out_buffer, out_pf, width, height, 1) <= 0) + { +#else + if(avpicture_fill( (AVPicture*)output_avframe, out_buffer, + out_pf, width, height ) <= 0) + { +#endif + Error("Failed filling output frame with output buffer"); + return -8; } /* Do the conversion */ @@ -338,15 +363,9 @@ void zm_dump_stream_format(AVFormatContext *ic, int i, int index, int is_output) int flags = (is_output ? ic->oformat->flags : ic->iformat->flags); AVStream *st = ic->streams[i]; AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0); - unsigned char *separator = ic->dump_separator; - char **codec_separator = (char **)av_opt_ptr(st->codec->av_class, st->codec, "dump_separator"); - int use_format_separator = !*codec_separator; + char separator = '\n'; - if (use_format_separator) - *codec_separator = av_strdup((const char *)separator); avcodec_string(buf, sizeof(buf), st->codec, is_output); - if (use_format_separator) - av_freep(codec_separator); Debug(3, " Stream #%d:%d", index, i); /* the pid is an important information, so we display it */ diff --git a/src/zm_ffmpeg.h b/src/zm_ffmpeg.h index ccd39ec40..ca74af2f8 100644 --- a/src/zm_ffmpeg.h +++ b/src/zm_ffmpeg.h @@ -48,6 +48,12 @@ extern "C" { #else #include #endif + +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) +#include +#else +#include +#endif #elif HAVE_FFMPEG_AVUTIL_H #include #include diff --git a/src/zm_ffmpeg_camera.cpp b/src/zm_ffmpeg_camera.cpp index 15d48c7d3..a6ca38e67 100644 --- a/src/zm_ffmpeg_camera.cpp +++ b/src/zm_ffmpeg_camera.cpp @@ -61,6 +61,7 @@ FfmpegCamera::FfmpegCamera( int p_id, const std::string &p_path, const std::stri mOpenStart = 0; mReopenThread = 0; wasRecording = false; + videoStore = NULL; #if HAVE_LIBSWSCALE mConvertContext = NULL; @@ -99,6 +100,7 @@ void FfmpegCamera::Initialise() av_log_set_level( AV_LOG_QUIET ); av_register_all(); + avformat_network_init(); } void FfmpegCamera::Terminate() @@ -191,7 +193,13 @@ int FfmpegCamera::Capture( Image &image ) if ( frameComplete ) { Debug( 4, "Got frame %d", frameCount ); - avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(mFrame->data, mFrame->linesize, + directbuffer, imagePixFormat, width, height, 1); +#else + avpicture_fill( (AVPicture *)mFrame, directbuffer, + imagePixFormat, width, height); +#endif #if HAVE_LIBSWSCALE if(mConvertContext == NULL) { @@ -350,7 +358,8 @@ int FfmpegCamera::OpenFfmpeg() { if ( mAudioStreamId == -1 ) Debug( 2, "Unable to locate audio stream in %s", mPath.c_str() ); - Debug ( 1, "Found video stream" ); + Debug ( 3, "Found video stream at index %d", mVideoStreamId ); + Debug ( 3, "Found audio stream at index %d", mAudioStreamId ); mCodecContext = mFormatContext->streams[mVideoStreamId]->codec; @@ -392,12 +401,17 @@ int FfmpegCamera::OpenFfmpeg() { Debug ( 1, "Allocated frames" ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 ); +#else int pSize = avpicture_get_size( imagePixFormat, width, height ); +#endif + if( (unsigned int)pSize != imagesize) { Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); } - Debug ( 1, "Validated imagesize" ); + Debug ( 1, "Validated imagesize %d", pSize ); #if HAVE_LIBSWSCALE Debug ( 1, "Calling sws_isSupportedInput" ); @@ -579,9 +593,11 @@ int FfmpegCamera::CaptureAndRecord( Image &image, bool recording, char* event_fi avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height); //Keep the last keyframe so we can establish immediate video - /*if(packet.flags & AV_PKT_FLAG_KEY) - av_copy_packet(&lastKeyframePkt, &packet);*/ - //TODO I think we need to store the key frame location for seeking as part of the event + if(packet.flags & AV_PKT_FLAG_KEY) { + //Debug(4, "Have keyframe"); + //av_copy_packet(&lastKeyframePkt, &packet); + //TODO I think we need to store the key frame location for seeking as part of the event + } //Video recording if ( recording && !wasRecording ) { @@ -591,6 +607,9 @@ int FfmpegCamera::CaptureAndRecord( Image &image, bool recording, char* event_fi videoStore = new VideoStore((const char *)event_file, "mp4", mFormatContext->streams[mVideoStreamId],mAudioStreamId==-1?NULL:mFormatContext->streams[mAudioStreamId],startTime); wasRecording = true; strcpy(oldDirectory, event_file); + + + // Need to write out all the frames from the last keyframe? } else if ( ( ! recording ) && wasRecording && videoStore ) { Info("Deleting videoStore instance"); @@ -649,9 +668,10 @@ int FfmpegCamera::CaptureAndRecord( Image &image, bool recording, char* event_fi } if ( videoStore && recording ) { if ( record_audio ) { - Debug(3, "Recording audio packet" ); + Debug(3, "Recording audio packet streamindex(%d) packetstreamindex(%d)", mAudioStreamId, packet.stream_index ); //Write the packet to our video store - int ret = videoStore->writeAudioFramePacket(&packet, mFormatContext->streams[packet.stream_index]); //FIXME no relevance of last key frame + //FIXME no relevance of last key frame + int ret = videoStore->writeAudioFramePacket( &packet, mFormatContext->streams[packet.stream_index] ); if ( ret < 0 ) {//Less than zero and we skipped a frame av_free_packet( &packet ); return 0; @@ -661,7 +681,11 @@ int FfmpegCamera::CaptureAndRecord( Image &image, bool recording, char* event_fi } } } else { +#if LIBAVUTIL_VERSION_CHECK(54, 23, 0, 23, 0) Debug( 3, "Some other stream index %d, %s", packet.stream_index, av_get_media_type_string( mFormatContext->streams[packet.stream_index]->codec->codec_type) ); +#else + Debug( 3, "Some other stream index %d", packet.stream_index ); +#endif } av_free_packet( &packet ); } // end while ! frameComplete diff --git a/src/zm_ffmpeg_camera.h b/src/zm_ffmpeg_camera.h index bc7ec2ecb..314ce6fa1 100644 --- a/src/zm_ffmpeg_camera.h +++ b/src/zm_ffmpeg_camera.h @@ -64,7 +64,9 @@ protected: bool wasRecording; VideoStore *videoStore; char oldDirectory[4096]; - //AVPacket lastKeyframePkt; + + // Last Key frame + AVPacket lastKeyframePkt; #if HAVE_LIBSWSCALE struct SwsContext *mConvertContext; diff --git a/src/zm_font.h b/src/zm_font.h index 844ff4f1e..cdad72dc4 100644 --- a/src/zm_font.h +++ b/src/zm_font.h @@ -1,3337 +1,3337 @@ /**********************************************/ -/* */ -/* Font file generated by rthelen */ -/* */ +/* */ +/* Font file generated by rthelen */ +/* */ /**********************************************/ static unsigned char fontdata[] = { - /* 0 0x00 '^A' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 1 0x01 '^B' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 2 0x02 '^C' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 3 0x03 '^D' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 4 0x04 '^E' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 5 0x05 '^F' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 6 0x06 '^G' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 7 0x07 '^H' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 8 0x08 '^I' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 9 0x09 '^J' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 10 0x0a '^K' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 11 0x0b '^L' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 12 0x0c '^M' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 13 0x0d '^N' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 14 0x0e '^O' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 15 0x0f '^P' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 16 0x10 '^Q' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 17 0x11 '^R' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x54, /* 0 0 0 00 */ - 0x38, /* 00 000 */ - 0x54, /* 0 0 0 00 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 18 0x12 '^S' */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x20, /* 00 00000 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 19 0x13 '^T' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x7c, /* 0 00 */ - 0x38, /* 00 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 20 0x14 '^U' */ - 0x18, /* 000 000 */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x7c, /* 0 00 */ - 0x78, /* 0 000 */ - 0x78, /* 0 000 */ - 0x7c, /* 0 00 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 21 0x15 '^V' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 22 0x16 '^W' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 23 0x17 '^X' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 24 0x18 '^Y' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 25 0x19 '^Z' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 26 0x1a '^[' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 27 0x1b '^\' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 28 0x1c '^]' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 29 0x1d '^^' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 30 0x1e '^_' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 31 0x1f '^`' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 32 0x20 ' ' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 33 0x21 '!' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 34 0x22 '"' */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 35 0x23 '#' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x7c, /* 0 00 */ - 0x28, /* 00 0 000 */ - 0x7c, /* 0 00 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 36 0x24 '$' */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x54, /* 0 0 0 00 */ - 0x50, /* 0 0 0000 */ - 0x38, /* 00 000 */ - 0x14, /* 000 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x38, /* 00 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 37 0x25 '%' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x58, /* 0 0 000 */ - 0x28, /* 00 0 000 */ - 0x34, /* 00 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x48, /* 0 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 38 0x26 '&' */ - 0x00, /* 00000000 */ - 0x30, /* 00 0000 */ - 0x48, /* 0 00 000 */ - 0x50, /* 0 0 0000 */ - 0x20, /* 00 00000 */ - 0x54, /* 0 0 0 00 */ - 0x48, /* 0 00 000 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 39 0x27 ''' */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 40 0x28 '(' */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x04, /* 00000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 41 0x29 ')' */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 42 0x2a '*' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x54, /* 0 0 0 00 */ - 0x38, /* 00 000 */ - 0x54, /* 0 0 0 00 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 43 0x2b '+' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 44 0x2c ',' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00 0000 */ - 0x30, /* 00 0000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ - - /* 45 0x2d '-' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 46 0x2e '.' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 000 000 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 47 0x2f '/' */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x20, /* 00 00000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x00, /* 00000000 */ - - /* 48 0x30 '0' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x64, /* 0 00 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 49 0x31 '1' */ - 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x18, /* 000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x1c, /* 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 50 0x32 '2' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 51 0x33 '3' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x04, /* 00000 00 */ - 0x18, /* 000 000 */ - 0x04, /* 00000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 52 0x34 '4' */ - 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x18, /* 000 000 */ - 0x28, /* 00 0 000 */ - 0x48, /* 0 00 000 */ - 0x7c, /* 0 00 */ - 0x08, /* 0000 000 */ - 0x1c, /* 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 53 0x35 '5' */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x78, /* 0 000 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 54 0x36 '6' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x40, /* 0 000000 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 55 0x37 '7' */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 56 0x38 '8' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 57 0x39 '9' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x3c, /* 00 00 */ - 0x04, /* 00000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 58 0x3a ':' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x18, /* 000 000 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x18, /* 000 000 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 59 0x3b ';' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x30, /* 00 0000 */ - 0x30, /* 00 0000 */ - 0x00, /* 00000000 */ - 0x30, /* 00 0000 */ - 0x30, /* 00 0000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ - - /* 60 0x3c '<' */ - 0x00, /* 00000000 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x04, /* 00000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 61 0x3d '=' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 62 0x3e '>' */ - 0x00, /* 00000000 */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 63 0x3f '?' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 64 0x40 '@' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x74, /* 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x78, /* 0 000 */ - 0x40, /* 0 000000 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 65 0x41 'A' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 66 0x42 'B' */ - 0x00, /* 00000000 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x78, /* 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 67 0x43 'C' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 68 0x44 'D' */ - 0x00, /* 00000000 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x78, /* 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 69 0x45 'E' */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x78, /* 0 000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 70 0x46 'F' */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x78, /* 0 000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 71 0x47 'G' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x40, /* 0 000000 */ - 0x4c, /* 0 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 72 0x48 'H' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 73 0x49 'I' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 74 0x4a 'J' */ - 0x00, /* 00000000 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 75 0x4b 'K' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x48, /* 0 00 000 */ - 0x50, /* 0 0 0000 */ - 0x60, /* 0 00000 */ - 0x50, /* 0 0 0000 */ - 0x48, /* 0 00 000 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 76 0x4c 'L' */ - 0x00, /* 00000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 77 0x4d 'M' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x6c, /* 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 78 0x4e 'N' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x64, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x4c, /* 0 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 79 0x4f 'O' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 80 0x50 'P' */ - 0x00, /* 00000000 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x78, /* 0 000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 81 0x51 'Q' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x54, /* 0 0 0 00 */ - 0x38, /* 00 000 */ - 0x04, /* 00000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 82 0x52 'R' */ - 0x00, /* 00000000 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 83 0x53 'S' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x40, /* 0 000000 */ - 0x38, /* 00 000 */ - 0x04, /* 00000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 84 0x54 'T' */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 85 0x55 'U' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 86 0x56 'V' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x28, /* 00 0 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 87 0x57 'W' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x6c, /* 0 0 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 88 0x58 'X' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x28, /* 00 0 000 */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 89 0x59 'Y' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x28, /* 00 0 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 90 0x5a 'Z' */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x40, /* 0 000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 91 0x5b '[' */ - 0x0c, /* 0000 00 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x0c, /* 0000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 92 0x5c '\' */ - 0x20, /* 00 00000 */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x02, /* 000000 0 */ - 0x02, /* 000000 0 */ - 0x00, /* 00000000 */ - - /* 93 0x5d ']' */ - 0x30, /* 00 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x30, /* 00 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 94 0x5e '^' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 95 0x5f '_' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 0 0 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 96 0x60 '`' */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 97 0x61 'a' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 98 0x62 'b' */ - 0x00, /* 00000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x78, /* 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 99 0x63 'c' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x40, /* 0 000000 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 100 0x64 'd' */ - 0x00, /* 00000000 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 101 0x65 'e' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 102 0x66 'f' */ - 0x00, /* 00000000 */ - 0x0c, /* 0000 00 */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 103 0x67 'g' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x3c, /* 00 00 */ - 0x04, /* 00000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - - /* 104 0x68 'h' */ - 0x00, /* 00000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 105 0x69 'i' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x30, /* 00 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 106 0x6a 'j' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x30, /* 00 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x60, /* 0 00000 */ - 0x00, /* 00000000 */ - - /* 107 0x6b 'k' */ - 0x00, /* 00000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x48, /* 0 00 000 */ - 0x50, /* 0 0 0000 */ - 0x70, /* 0 0000 */ - 0x48, /* 0 00 000 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 108 0x6c 'l' */ - 0x00, /* 00000000 */ - 0x30, /* 00 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 109 0x6d 'm' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 0 000 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 110 0x6e 'n' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x58, /* 0 0 000 */ - 0x64, /* 0 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 111 0x6f 'o' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 112 0x70 'p' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x78, /* 0 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x78, /* 0 000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x00, /* 00000000 */ - - /* 113 0x71 'q' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x3c, /* 00 00 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x00, /* 00000000 */ - - /* 114 0x72 'r' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x58, /* 0 0 000 */ - 0x64, /* 0 00 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 115 0x73 's' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x40, /* 0 000000 */ - 0x38, /* 00 000 */ - 0x04, /* 00000 00 */ - 0x78, /* 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 116 0x74 't' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x0c, /* 0000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 117 0x75 'u' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 118 0x76 'v' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x28, /* 00 0 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 119 0x77 'w' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 120 0x78 'x' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x28, /* 00 0 000 */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 121 0x79 'y' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x3c, /* 00 00 */ - 0x04, /* 00000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - - /* 122 0x7a 'z' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 123 0x7b '{' */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x04, /* 00000 00 */ - 0x00, /* 00000000 */ - - /* 124 0x7c '|' */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 125 0x7d '}' */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ - - /* 126 0x7e '~' */ - 0x00, /* 00000000 */ - 0x34, /* 00 0 00 */ - 0x58, /* 0 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 127 0x7f '^?' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 128 0x80 '\200' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 129 0x81 '\201' */ - 0x28, /* 00 0 000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 130 0x82 '\202' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 131 0x83 '\203' */ - 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x78, /* 0 000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 132 0x84 '\204' */ - 0x58, /* 0 0 000 */ - 0x44, /* 0 000 00 */ - 0x64, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x4c, /* 0 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 133 0x85 '\205' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 134 0x86 '\206' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 135 0x87 '\207' */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 136 0x88 '\210' */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 137 0x89 '\211' */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 138 0x8a '\212' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 139 0x8b '\213' */ - 0x34, /* 00 0 00 */ - 0x58, /* 0 0 000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 140 0x8c '\214' */ - 0x18, /* 000 000 */ - 0x24, /* 00 00 00 */ - 0x18, /* 000 000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 141 0x8d '\215' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x3c, /* 00 00 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ - - /* 142 0x8e '\216' */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 143 0x8f '\217' */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 144 0x90 '\220' */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 145 0x91 '\221' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 146 0x92 '\222' */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 147 0x93 '\223' */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 148 0x94 '\224' */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 149 0x95 '\225' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 150 0x96 '\226' */ - 0x34, /* 00 0 00 */ - 0x58, /* 0 0 000 */ - 0x00, /* 00000000 */ - 0x58, /* 0 0 000 */ - 0x64, /* 0 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 151 0x97 '\227' */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 152 0x98 '\230' */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 153 0x99 '\231' */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 154 0x9a '\232' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 155 0x9b '\233' */ - 0x34, /* 00 0 00 */ - 0x58, /* 0 0 000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 156 0x9c '\234' */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 157 0x9d '\235' */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 158 0x9e '\236' */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 159 0x9f '\237' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 160 0xa0 '\240' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 161 0xa1 '\241' */ - 0x18, /* 000 000 */ - 0x24, /* 00 00 00 */ - 0x24, /* 00 00 00 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 162 0xa2 '\242' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x54, /* 0 0 0 00 */ - 0x50, /* 0 0 0000 */ - 0x54, /* 0 0 0 00 */ - 0x38, /* 00 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 163 0xa3 '\243' */ - 0x30, /* 00 0000 */ - 0x48, /* 0 00 000 */ - 0x40, /* 0 000000 */ - 0x70, /* 0 0000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x44, /* 0 000 00 */ - 0x78, /* 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 164 0xa4 '\244' */ - 0x44, /* 0 000 00 */ - 0x24, /* 00 00 00 */ - 0x50, /* 0 0 0000 */ - 0x48, /* 0 00 000 */ - 0x24, /* 00 00 00 */ - 0x14, /* 000 0 00 */ - 0x48, /* 0 00 000 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 165 0xa5 '\245' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x7c, /* 0 00 */ - 0x7c, /* 0 00 */ - 0x7c, /* 0 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 166 0xa6 '\246' */ - 0x3c, /* 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x3c, /* 00 00 */ - 0x14, /* 000 0 00 */ - 0x14, /* 000 0 00 */ - 0x14, /* 000 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 167 0xa7 '\247' */ - 0x18, /* 000 000 */ - 0x24, /* 00 00 00 */ - 0x44, /* 0 000 00 */ - 0x48, /* 0 00 000 */ - 0x48, /* 0 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x58, /* 0 0 000 */ - 0x40, /* 0 000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 168 0xa8 '\250' */ - 0x00, /* 00000000 */ - 0x70, /* 0 0000 */ - 0x08, /* 0000 000 */ - 0x64, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x64, /* 0 00 00 */ - 0x58, /* 0 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 169 0xa9 '\251' */ - 0x00, /* 00000000 */ - 0x70, /* 0 0000 */ - 0x08, /* 0000 000 */ - 0x34, /* 00 0 00 */ - 0x44, /* 0 000 00 */ - 0x34, /* 00 0 00 */ - 0x08, /* 0000 000 */ - 0x70, /* 0 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 170 0xaa '\252' */ - 0x00, /* 00000000 */ - 0x7a, /* 0 0 0 */ - 0x2e, /* 00 0 0 */ - 0x2e, /* 00 0 0 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 171 0xab '\253' */ - 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 172 0xac '\254' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 173 0xad '\255' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 174 0xae '\256' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x78, /* 0 000 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x5c, /* 0 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 175 0xaf '\257' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x64, /* 0 00 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 176 0xb0 '\260' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x6c, /* 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x6c, /* 0 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 177 0xb1 '\261' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 178 0xb2 '\262' */ - 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 179 0xb3 '\263' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x1c, /* 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 180 0xb4 '\264' */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x28, /* 00 0 000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 181 0xb5 '\265' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x48, /* 0 00 000 */ - 0x48, /* 0 00 000 */ - 0x48, /* 0 00 000 */ - 0x48, /* 0 00 000 */ - 0x74, /* 0 0 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x00, /* 00000000 */ - - /* 182 0xb6 '\266' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x0c, /* 0000 00 */ - 0x14, /* 000 0 00 */ - 0x24, /* 00 00 00 */ - 0x24, /* 00 00 00 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 183 0xb7 '\267' */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x24, /* 00 00 00 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x24, /* 00 00 00 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 184 0xb8 '\270' */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 185 0xb9 '\271' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 186 0xba '\272' */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x60, /* 0 00000 */ - 0x00, /* 00000000 */ - - /* 187 0xbb '\273' */ - 0x00, /* 00000000 */ - 0x1c, /* 000 00 */ - 0x24, /* 00 00 00 */ - 0x24, /* 00 00 00 */ - 0x1c, /* 000 00 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 188 0xbc '\274' */ - 0x00, /* 00000000 */ - 0x18, /* 000 000 */ - 0x24, /* 00 00 00 */ - 0x24, /* 00 00 00 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 189 0xbd '\275' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x28, /* 00 0 000 */ - 0x6c, /* 0 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 190 0xbe '\276' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x54, /* 0 0 0 00 */ - 0x5c, /* 0 0 00 */ - 0x50, /* 0 0 0000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 191 0xbf '\277' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x4c, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x64, /* 0 00 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 192 0xc0 '\300' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x40, /* 0 000000 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 193 0xc1 '\301' */ - 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 194 0xc2 '\302' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 195 0xc3 '\303' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x0c, /* 0000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x50, /* 0 0 0000 */ - 0x20, /* 00 00000 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 196 0xc4 '\304' */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x60, /* 0 00000 */ - 0x00, /* 00000000 */ - - /* 197 0xc5 '\305' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x04, /* 00000 00 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x40, /* 0 000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 198 0xc6 '\306' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 199 0xc7 '\307' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x24, /* 00 00 00 */ - 0x48, /* 0 00 000 */ - 0x48, /* 0 00 000 */ - 0x24, /* 00 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 200 0xc8 '\310' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x48, /* 0 00 000 */ - 0x24, /* 00 00 00 */ - 0x24, /* 00 00 00 */ - 0x48, /* 0 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 201 0xc9 '\311' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x54, /* 0 0 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 202 0xca '\312' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 203 0xcb '\313' */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 204 0xcc '\314' */ - 0x58, /* 0 0 000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 205 0xcd '\315' */ - 0x58, /* 0 0 000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 206 0xce '\316' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x58, /* 0 0 000 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 207 0xcf '\317' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x54, /* 0 0 0 00 */ - 0x5c, /* 0 0 00 */ - 0x50, /* 0 0 0000 */ - 0x2c, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 208 0xd0 '\320' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 209 0xd1 '\321' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 0 0 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 210 0xd2 '\322' */ - 0x00, /* 00000000 */ - 0x14, /* 000 0 00 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 211 0xd3 '\323' */ - 0x00, /* 00000000 */ - 0x14, /* 000 0 00 */ - 0x14, /* 000 0 00 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 212 0xd4 '\324' */ - 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 213 0xd5 '\325' */ - 0x00, /* 00000000 */ - 0x18, /* 000 000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 214 0xd6 '\326' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 215 0xd7 '\327' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x44, /* 0 000 00 */ - 0x28, /* 00 0 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 216 0xd8 '\330' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x3c, /* 00 00 */ - 0x04, /* 00000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - - /* 217 0xd9 '\331' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x7e, /* 0 0 */ - 0x00, /* 00000000 */ - 0x7e, /* 0 0 */ - 0x00, /* 00000000 */ - 0x7e, /* 0 0 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 218 0xda '\332' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 219 0xdb '\333' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 220 0xdc '\334' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 221 0xdd '\335' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 222 0xde '\336' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 223 0xdf '\337' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 224 0xe0 '\340' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 225 0xe1 '\341' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 226 0xe2 '\342' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 227 0xe3 '\343' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 228 0xe4 '\344' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 229 0xe5 '\345' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 230 0xe6 '\346' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 231 0xe7 '\347' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 232 0xe8 '\350' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 233 0xe9 '\351' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 234 0xea '\352' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 235 0xeb '\353' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 236 0xec '\354' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 237 0xed '\355' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 238 0xee '\356' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 239 0xef '\357' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 240 0xf0 '\360' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 241 0xf1 '\361' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 242 0xf2 '\362' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 243 0xf3 '\363' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 244 0xf4 '\364' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 245 0xf5 '\365' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 246 0xf6 '\366' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 247 0xf7 '\367' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 248 0xf8 '\370' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 249 0xf9 '\371' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 250 0xfa '\372' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 251 0xfb '\373' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 252 0xfc '\374' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 253 0xfd '\375' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 254 0xfe '\376' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 255 0xff '\377' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 0 0x00 '^A' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 1 0x01 '^B' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 2 0x02 '^C' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 3 0x03 '^D' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 4 0x04 '^E' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 5 0x05 '^F' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 6 0x06 '^G' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 7 0x07 '^H' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 8 0x08 '^I' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 9 0x09 '^J' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 10 0x0a '^K' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 11 0x0b '^L' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 12 0x0c '^M' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 13 0x0d '^N' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 14 0x0e '^O' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 15 0x0f '^P' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 16 0x10 '^Q' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 17 0x11 '^R' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 18 0x12 '^S' */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x50, /* 0 0 0000 */ + 0x50, /* 0 0 0000 */ + 0x20, /* 00 00000 */ + 0x20, /* 00 00000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 19 0x13 '^T' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x7c, /* 0 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 20 0x14 '^U' */ + 0x18, /* 000 000 */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x7c, /* 0 00 */ + 0x78, /* 0 000 */ + 0x78, /* 0 000 */ + 0x7c, /* 0 00 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 21 0x15 '^V' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 22 0x16 '^W' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 23 0x17 '^X' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 24 0x18 '^Y' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 25 0x19 '^Z' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 26 0x1a '^[' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 27 0x1b '^\' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 28 0x1c '^]' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 29 0x1d '^^' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 30 0x1e '^_' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 31 0x1f '^`' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 32 0x20 ' ' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 33 0x21 '!' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 34 0x22 '"' */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 35 0x23 '#' */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x7c, /* 0 00 */ + 0x28, /* 00 0 000 */ + 0x7c, /* 0 00 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 36 0x24 '$' */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x50, /* 0 0 0000 */ + 0x38, /* 00 000 */ + 0x14, /* 000 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 37 0x25 '%' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x58, /* 0 0 000 */ + 0x28, /* 00 0 000 */ + 0x34, /* 00 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x48, /* 0 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 38 0x26 '&' */ + 0x00, /* 00000000 */ + 0x30, /* 00 0000 */ + 0x48, /* 0 00 000 */ + 0x50, /* 0 0 0000 */ + 0x20, /* 00 00000 */ + 0x54, /* 0 0 0 00 */ + 0x48, /* 0 00 000 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 39 0x27 ''' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 40 0x28 '(' */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x04, /* 00000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 41 0x29 ')' */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 42 0x2a '*' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 43 0x2b '+' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 44 0x2c ',' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00 0000 */ + 0x30, /* 00 0000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x00, /* 00000000 */ + + /* 45 0x2d '-' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 46 0x2e '.' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 000 000 */ + 0x18, /* 000 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 47 0x2f '/' */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x20, /* 00 00000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x00, /* 00000000 */ + + /* 48 0x30 '0' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x64, /* 0 00 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 49 0x31 '1' */ + 0x00, /* 00000000 */ + 0x08, /* 0000 000 */ + 0x18, /* 000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x1c, /* 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 50 0x32 '2' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 51 0x33 '3' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x04, /* 00000 00 */ + 0x18, /* 000 000 */ + 0x04, /* 00000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 52 0x34 '4' */ + 0x00, /* 00000000 */ + 0x08, /* 0000 000 */ + 0x18, /* 000 000 */ + 0x28, /* 00 0 000 */ + 0x48, /* 0 00 000 */ + 0x7c, /* 0 00 */ + 0x08, /* 0000 000 */ + 0x1c, /* 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 53 0x35 '5' */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 54 0x36 '6' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 55 0x37 '7' */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 56 0x38 '8' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 57 0x39 '9' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x3c, /* 00 00 */ + 0x04, /* 00000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 58 0x3a ':' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x18, /* 000 000 */ + 0x18, /* 000 000 */ + 0x00, /* 00000000 */ + 0x18, /* 000 000 */ + 0x18, /* 000 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 59 0x3b ';' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x30, /* 00 0000 */ + 0x30, /* 00 0000 */ + 0x00, /* 00000000 */ + 0x30, /* 00 0000 */ + 0x30, /* 00 0000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x00, /* 00000000 */ + + /* 60 0x3c '<' */ + 0x00, /* 00000000 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x04, /* 00000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 61 0x3d '=' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 62 0x3e '>' */ + 0x00, /* 00000000 */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 63 0x3f '?' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 64 0x40 '@' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x74, /* 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x78, /* 0 000 */ + 0x40, /* 0 000000 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 65 0x41 'A' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 66 0x42 'B' */ + 0x00, /* 00000000 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x78, /* 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 67 0x43 'C' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 68 0x44 'D' */ + 0x00, /* 00000000 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x78, /* 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 69 0x45 'E' */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 70 0x46 'F' */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 71 0x47 'G' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x40, /* 0 000000 */ + 0x4c, /* 0 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 72 0x48 'H' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 73 0x49 'I' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 74 0x4a 'J' */ + 0x00, /* 00000000 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 75 0x4b 'K' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x48, /* 0 00 000 */ + 0x50, /* 0 0 0000 */ + 0x60, /* 0 00000 */ + 0x50, /* 0 0 0000 */ + 0x48, /* 0 00 000 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 76 0x4c 'L' */ + 0x00, /* 00000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 77 0x4d 'M' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x6c, /* 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 78 0x4e 'N' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x64, /* 0 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x4c, /* 0 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 79 0x4f 'O' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 80 0x50 'P' */ + 0x00, /* 00000000 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x78, /* 0 000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 81 0x51 'Q' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ + 0x04, /* 00000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 82 0x52 'R' */ + 0x00, /* 00000000 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 83 0x53 'S' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x40, /* 0 000000 */ + 0x38, /* 00 000 */ + 0x04, /* 00000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 84 0x54 'T' */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 85 0x55 'U' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 86 0x56 'V' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 87 0x57 'W' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x6c, /* 0 0 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 88 0x58 'X' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 89 0x59 'Y' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 90 0x5a 'Z' */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x40, /* 0 000000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 91 0x5b '[' */ + 0x0c, /* 0000 00 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x0c, /* 0000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 92 0x5c '\' */ + 0x20, /* 00 00000 */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x02, /* 000000 0 */ + 0x02, /* 000000 0 */ + 0x00, /* 00000000 */ + + /* 93 0x5d ']' */ + 0x30, /* 00 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x30, /* 00 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 94 0x5e '^' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 95 0x5f '_' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 0 0 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 96 0x60 '`' */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 97 0x61 'a' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 98 0x62 'b' */ + 0x00, /* 00000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x78, /* 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 99 0x63 'c' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x40, /* 0 000000 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 100 0x64 'd' */ + 0x00, /* 00000000 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 101 0x65 'e' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 102 0x66 'f' */ + 0x00, /* 00000000 */ + 0x0c, /* 0000 00 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 103 0x67 'g' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x3c, /* 00 00 */ + 0x04, /* 00000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + + /* 104 0x68 'h' */ + 0x00, /* 00000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 105 0x69 'i' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x30, /* 00 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 106 0x6a 'j' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x30, /* 00 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x60, /* 0 00000 */ + 0x00, /* 00000000 */ + + /* 107 0x6b 'k' */ + 0x00, /* 00000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x48, /* 0 00 000 */ + 0x50, /* 0 0 0000 */ + 0x70, /* 0 0000 */ + 0x48, /* 0 00 000 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 108 0x6c 'l' */ + 0x00, /* 00000000 */ + 0x30, /* 00 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 109 0x6d 'm' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 0 000 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 110 0x6e 'n' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x58, /* 0 0 000 */ + 0x64, /* 0 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 111 0x6f 'o' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 112 0x70 'p' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x78, /* 0 000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x00, /* 00000000 */ + + /* 113 0x71 'q' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x3c, /* 00 00 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x00, /* 00000000 */ + + /* 114 0x72 'r' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x58, /* 0 0 000 */ + 0x64, /* 0 00 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 115 0x73 's' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x40, /* 0 000000 */ + 0x38, /* 00 000 */ + 0x04, /* 00000 00 */ + 0x78, /* 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 116 0x74 't' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x0c, /* 0000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 117 0x75 'u' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 118 0x76 'v' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 119 0x77 'w' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 120 0x78 'x' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 121 0x79 'y' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x3c, /* 00 00 */ + 0x04, /* 00000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + + /* 122 0x7a 'z' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 123 0x7b '{' */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x04, /* 00000 00 */ + 0x00, /* 00000000 */ + + /* 124 0x7c '|' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 125 0x7d '}' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x00, /* 00000000 */ + + /* 126 0x7e '~' */ + 0x00, /* 00000000 */ + 0x34, /* 00 0 00 */ + 0x58, /* 0 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 127 0x7f '^?' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 128 0x80 '\200' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 129 0x81 '\201' */ + 0x28, /* 00 0 000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 130 0x82 '\202' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 131 0x83 '\203' */ + 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 132 0x84 '\204' */ + 0x58, /* 0 0 000 */ + 0x44, /* 0 000 00 */ + 0x64, /* 0 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x4c, /* 0 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 133 0x85 '\205' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 134 0x86 '\206' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 135 0x87 '\207' */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 136 0x88 '\210' */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 137 0x89 '\211' */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 138 0x8a '\212' */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 139 0x8b '\213' */ + 0x34, /* 00 0 00 */ + 0x58, /* 0 0 000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 140 0x8c '\214' */ + 0x18, /* 000 000 */ + 0x24, /* 00 00 00 */ + 0x18, /* 000 000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 141 0x8d '\215' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x3c, /* 00 00 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x00, /* 00000000 */ + + /* 142 0x8e '\216' */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 143 0x8f '\217' */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 144 0x90 '\220' */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 145 0x91 '\221' */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 146 0x92 '\222' */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 147 0x93 '\223' */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 148 0x94 '\224' */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 149 0x95 '\225' */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 150 0x96 '\226' */ + 0x34, /* 00 0 00 */ + 0x58, /* 0 0 000 */ + 0x00, /* 00000000 */ + 0x58, /* 0 0 000 */ + 0x64, /* 0 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 151 0x97 '\227' */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 152 0x98 '\230' */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 153 0x99 '\231' */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 154 0x9a '\232' */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 155 0x9b '\233' */ + 0x34, /* 00 0 00 */ + 0x58, /* 0 0 000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 156 0x9c '\234' */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 157 0x9d '\235' */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 158 0x9e '\236' */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 159 0x9f '\237' */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 160 0xa0 '\240' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 161 0xa1 '\241' */ + 0x18, /* 000 000 */ + 0x24, /* 00 00 00 */ + 0x24, /* 00 00 00 */ + 0x18, /* 000 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 162 0xa2 '\242' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x50, /* 0 0 0000 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 163 0xa3 '\243' */ + 0x30, /* 00 0000 */ + 0x48, /* 0 00 000 */ + 0x40, /* 0 000000 */ + 0x70, /* 0 0000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x44, /* 0 000 00 */ + 0x78, /* 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 164 0xa4 '\244' */ + 0x44, /* 0 000 00 */ + 0x24, /* 00 00 00 */ + 0x50, /* 0 0 0000 */ + 0x48, /* 0 00 000 */ + 0x24, /* 00 00 00 */ + 0x14, /* 000 0 00 */ + 0x48, /* 0 00 000 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 165 0xa5 '\245' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x7c, /* 0 00 */ + 0x7c, /* 0 00 */ + 0x7c, /* 0 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 166 0xa6 '\246' */ + 0x3c, /* 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x3c, /* 00 00 */ + 0x14, /* 000 0 00 */ + 0x14, /* 000 0 00 */ + 0x14, /* 000 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 167 0xa7 '\247' */ + 0x18, /* 000 000 */ + 0x24, /* 00 00 00 */ + 0x44, /* 0 000 00 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x58, /* 0 0 000 */ + 0x40, /* 0 000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 168 0xa8 '\250' */ + 0x00, /* 00000000 */ + 0x70, /* 0 0000 */ + 0x08, /* 0000 000 */ + 0x64, /* 0 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x64, /* 0 00 00 */ + 0x58, /* 0 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 169 0xa9 '\251' */ + 0x00, /* 00000000 */ + 0x70, /* 0 0000 */ + 0x08, /* 0000 000 */ + 0x34, /* 00 0 00 */ + 0x44, /* 0 000 00 */ + 0x34, /* 00 0 00 */ + 0x08, /* 0000 000 */ + 0x70, /* 0 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 170 0xaa '\252' */ + 0x00, /* 00000000 */ + 0x7a, /* 0 0 0 */ + 0x2e, /* 00 0 0 */ + 0x2e, /* 00 0 0 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 171 0xab '\253' */ + 0x00, /* 00000000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 172 0xac '\254' */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 173 0xad '\255' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x08, /* 0000 000 */ + 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ + 0x20, /* 00 00000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 174 0xae '\256' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x50, /* 0 0 0000 */ + 0x50, /* 0 0 0000 */ + 0x78, /* 0 000 */ + 0x50, /* 0 0 0000 */ + 0x50, /* 0 0 0000 */ + 0x5c, /* 0 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 175 0xaf '\257' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x64, /* 0 00 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 176 0xb0 '\260' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x6c, /* 0 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 177 0xb1 '\261' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 178 0xb2 '\262' */ + 0x00, /* 00000000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 179 0xb3 '\263' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x1c, /* 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 180 0xb4 '\264' */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 181 0xb5 '\265' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x74, /* 0 0 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x00, /* 00000000 */ + + /* 182 0xb6 '\266' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x0c, /* 0000 00 */ + 0x14, /* 000 0 00 */ + 0x24, /* 00 00 00 */ + 0x24, /* 00 00 00 */ + 0x18, /* 000 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 183 0xb7 '\267' */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x24, /* 00 00 00 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x24, /* 00 00 00 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 184 0xb8 '\270' */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 185 0xb9 '\271' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 186 0xba '\272' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x60, /* 0 00000 */ + 0x00, /* 00000000 */ + + /* 187 0xbb '\273' */ + 0x00, /* 00000000 */ + 0x1c, /* 000 00 */ + 0x24, /* 00 00 00 */ + 0x24, /* 00 00 00 */ + 0x1c, /* 000 00 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 188 0xbc '\274' */ + 0x00, /* 00000000 */ + 0x18, /* 000 000 */ + 0x24, /* 00 00 00 */ + 0x24, /* 00 00 00 */ + 0x18, /* 000 000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 189 0xbd '\275' */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x6c, /* 0 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 190 0xbe '\276' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x5c, /* 0 0 00 */ + 0x50, /* 0 0 0000 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 191 0xbf '\277' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x4c, /* 0 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x64, /* 0 00 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 192 0xc0 '\300' */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x40, /* 0 000000 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 193 0xc1 '\301' */ + 0x00, /* 00000000 */ + 0x08, /* 0000 000 */ + 0x00, /* 00000000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 194 0xc2 '\302' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 195 0xc3 '\303' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x0c, /* 0000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x50, /* 0 0 0000 */ + 0x20, /* 00 00000 */ + 0x20, /* 00 00000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 196 0xc4 '\304' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x60, /* 0 00000 */ + 0x00, /* 00000000 */ + + /* 197 0xc5 '\305' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x04, /* 00000 00 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x40, /* 0 000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 198 0xc6 '\306' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 199 0xc7 '\307' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x24, /* 00 00 00 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x24, /* 00 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 200 0xc8 '\310' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x48, /* 0 00 000 */ + 0x24, /* 00 00 00 */ + 0x24, /* 00 00 00 */ + 0x48, /* 0 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 201 0xc9 '\311' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x54, /* 0 0 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 202 0xca '\312' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 203 0xcb '\313' */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 204 0xcc '\314' */ + 0x58, /* 0 0 000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 205 0xcd '\315' */ + 0x58, /* 0 0 000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 206 0xce '\316' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x50, /* 0 0 0000 */ + 0x50, /* 0 0 0000 */ + 0x58, /* 0 0 000 */ + 0x50, /* 0 0 0000 */ + 0x50, /* 0 0 0000 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 207 0xcf '\317' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x54, /* 0 0 0 00 */ + 0x5c, /* 0 0 00 */ + 0x50, /* 0 0 0000 */ + 0x2c, /* 00 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 208 0xd0 '\320' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 209 0xd1 '\321' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 0 0 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 210 0xd2 '\322' */ + 0x00, /* 00000000 */ + 0x14, /* 000 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 211 0xd3 '\323' */ + 0x00, /* 00000000 */ + 0x14, /* 000 0 00 */ + 0x14, /* 000 0 00 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 212 0xd4 '\324' */ + 0x00, /* 00000000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x18, /* 000 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 213 0xd5 '\325' */ + 0x00, /* 00000000 */ + 0x18, /* 000 000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 214 0xd6 '\326' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 215 0xd7 '\327' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 216 0xd8 '\330' */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x3c, /* 00 00 */ + 0x04, /* 00000 00 */ + 0x38, /* 00 000 */ + 0x00, /* 00000000 */ + + /* 217 0xd9 '\331' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7e, /* 0 0 */ + 0x00, /* 00000000 */ + 0x7e, /* 0 0 */ + 0x00, /* 00000000 */ + 0x7e, /* 0 0 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 218 0xda '\332' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 219 0xdb '\333' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 220 0xdc '\334' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 221 0xdd '\335' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 222 0xde '\336' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 223 0xdf '\337' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 224 0xe0 '\340' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 225 0xe1 '\341' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 226 0xe2 '\342' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 227 0xe3 '\343' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 228 0xe4 '\344' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 229 0xe5 '\345' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 230 0xe6 '\346' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 231 0xe7 '\347' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 232 0xe8 '\350' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 233 0xe9 '\351' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 234 0xea '\352' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 235 0xeb '\353' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 236 0xec '\354' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 237 0xed '\355' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 238 0xee '\356' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 239 0xef '\357' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 240 0xf0 '\360' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 241 0xf1 '\361' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 242 0xf2 '\362' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 243 0xf3 '\363' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 244 0xf4 '\364' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 245 0xf5 '\365' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 246 0xf6 '\366' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 247 0xf7 '\367' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 248 0xf8 '\370' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 249 0xf9 '\371' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 250 0xfa '\372' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 251 0xfb '\373' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 252 0xfc '\374' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 253 0xfd '\375' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 254 0xfe '\376' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 255 0xff '\377' */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ }; diff --git a/src/zm_image.cpp b/src/zm_image.cpp index a302b4be5..d76384dc3 100644 --- a/src/zm_image.cpp +++ b/src/zm_image.cpp @@ -63,729 +63,729 @@ imgbufcpy_fptr_t fptr_imgbufcpy; Image::Image() { - if ( !initialised ) - Initialise(); - width = 0; - height = 0; - pixels = 0; - colours = 0; - subpixelorder = 0; - size = 0; - allocation = 0; - buffer = 0; - buffertype = 0; - holdbuffer = 0; - text[0] = '\0'; + if ( !initialised ) + Initialise(); + width = 0; + height = 0; + pixels = 0; + colours = 0; + subpixelorder = 0; + size = 0; + allocation = 0; + buffer = 0; + buffertype = 0; + holdbuffer = 0; + text[0] = '\0'; } Image::Image( const char *filename ) { - if ( !initialised ) - Initialise(); - width = 0; - height = 0; - pixels = 0; - colours = 0; - subpixelorder = 0; - size = 0; - allocation = 0; - buffer = 0; - buffertype = 0; - holdbuffer = 0; - ReadJpeg( filename, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB); - text[0] = '\0'; + if ( !initialised ) + Initialise(); + width = 0; + height = 0; + pixels = 0; + colours = 0; + subpixelorder = 0; + size = 0; + allocation = 0; + buffer = 0; + buffertype = 0; + holdbuffer = 0; + ReadJpeg( filename, ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB); + text[0] = '\0'; } Image::Image( int p_width, int p_height, int p_colours, int p_subpixelorder, uint8_t *p_buffer ) { - if ( !initialised ) - Initialise(); - width = p_width; - height = p_height; - pixels = width*height; - colours = p_colours; - subpixelorder = p_subpixelorder; - size = pixels*colours; - buffer = 0; - holdbuffer = 0; - if ( p_buffer ) - { - allocation = size; - buffertype = ZM_BUFTYPE_DONTFREE; - buffer = p_buffer; - } - else - { - AllocImgBuffer(size); - } - text[0] = '\0'; + if ( !initialised ) + Initialise(); + width = p_width; + height = p_height; + pixels = width*height; + colours = p_colours; + subpixelorder = p_subpixelorder; + size = pixels*colours; + buffer = 0; + holdbuffer = 0; + if ( p_buffer ) + { + allocation = size; + buffertype = ZM_BUFTYPE_DONTFREE; + buffer = p_buffer; + } + else + { + AllocImgBuffer(size); + } + text[0] = '\0'; } Image::Image( const Image &p_image ) { - if ( !initialised ) - Initialise(); - width = p_image.width; - height = p_image.height; - pixels = p_image.pixels; - colours = p_image.colours; - subpixelorder = p_image.subpixelorder; - size = p_image.size; // allocation is set in AllocImgBuffer - buffer = 0; - holdbuffer = 0; - AllocImgBuffer(size); - (*fptr_imgbufcpy)(buffer, p_image.buffer, size); - strncpy( text, p_image.text, sizeof(text) ); + if ( !initialised ) + Initialise(); + width = p_image.width; + height = p_image.height; + pixels = p_image.pixels; + colours = p_image.colours; + subpixelorder = p_image.subpixelorder; + size = p_image.size; // allocation is set in AllocImgBuffer + buffer = 0; + holdbuffer = 0; + AllocImgBuffer(size); + (*fptr_imgbufcpy)(buffer, p_image.buffer, size); + strncpy( text, p_image.text, sizeof(text) ); } Image::~Image() { - DumpImgBuffer(); - if ( initialised ) - { - delete[] y_table; - delete[] uv_table; - delete[] r_v_table; - delete[] g_v_table; - delete[] g_u_table; - delete[] b_u_table; - initialised = false; - } - if ( jpg_dcinfo ) - { - jpeg_destroy_decompress( jpg_dcinfo ); - delete jpg_dcinfo; - jpg_dcinfo = 0; - } + DumpImgBuffer(); + if ( initialised ) + { + delete[] y_table; + delete[] uv_table; + delete[] r_v_table; + delete[] g_v_table; + delete[] g_u_table; + delete[] b_u_table; + initialised = false; + } + if ( jpg_dcinfo ) + { + jpeg_destroy_decompress( jpg_dcinfo ); + delete jpg_dcinfo; + jpg_dcinfo = 0; + } } void Image::Initialise() { - /* Assign the blend pointer to function */ - if(config.fast_image_blends) { - if(config.cpu_extensions && sseversion >= 20) { - fptr_blend = &sse2_fastblend; /* SSE2 fast blend */ - Debug(2,"Blend: Using SSE2 fast blend function"); - } else { - fptr_blend = &std_fastblend; /* standard fast blend */ - Debug(2,"Blend: Using fast blend function"); - } - } else { - fptr_blend = &std_blend; - Debug(2,"Blend: Using standard blend function"); - } - - __attribute__((aligned(16))) uint8_t blend1[16] = {142,255,159,91,88,227,0,52,37,80,152,97,104,252,90,82}; - __attribute__((aligned(16))) uint8_t blend2[16] = {129,56,136,96,119,149,94,29,96,176,1,144,230,203,111,172}; - __attribute__((aligned(16))) uint8_t blendres[16]; - __attribute__((aligned(16))) uint8_t blendexp[16] = {141,231,157,92,91,217,11,49,45,92,133,103,119,246,92,93}; /* Expected results for 12.5% blend */ - - (*fptr_blend)(blend1,blend2,blendres,16,12.5); - - /* Compare results with expected results */ - for(int i=0;i<16;i++) { - if(abs(blendexp[i] - blendres[i]) > 3) { - Panic("Blend function failed self-test: Results differ from the expected results"); - } - } - - fptr_delta8_rgb = &std_delta8_rgb; - fptr_delta8_bgr = &std_delta8_bgr; - - /* Assign the delta functions */ - if(config.cpu_extensions) { - if(sseversion >= 35) { - /* SSSE3 available */ - fptr_delta8_rgba = &ssse3_delta8_rgba; - fptr_delta8_bgra = &ssse3_delta8_bgra; - fptr_delta8_argb = &ssse3_delta8_argb; - fptr_delta8_abgr = &ssse3_delta8_abgr; - fptr_delta8_gray8 = &sse2_delta8_gray8; - Debug(2,"Delta: Using SSSE3 delta functions"); - } else if(sseversion >= 20) { - /* SSE2 available */ - fptr_delta8_rgba = &sse2_delta8_rgba; - fptr_delta8_bgra = &sse2_delta8_bgra; - fptr_delta8_argb = &sse2_delta8_argb; - fptr_delta8_abgr = &sse2_delta8_abgr; - /* - ** On some systems, the 4 SSE2 algorithms above might be a little slower than - ** the standard algorithms, especially on early Pentium 4 processors. - ** In that case, comment out the 4 lines above and uncomment the 4 lines below - */ - // fptr_delta8_rgba = &std_delta8_rgba; - // fptr_delta8_bgra = &std_delta8_bgra; - // fptr_delta8_argb = &std_delta8_argb; - // fptr_delta8_abgr = &std_delta8_abgr; - fptr_delta8_gray8 = &sse2_delta8_gray8; - Debug(2,"Delta: Using SSE2 delta functions"); - } else { - /* No suitable SSE version available */ - fptr_delta8_rgba = &std_delta8_rgba; - fptr_delta8_bgra = &std_delta8_bgra; - fptr_delta8_argb = &std_delta8_argb; - fptr_delta8_abgr = &std_delta8_abgr; - fptr_delta8_gray8 = &std_delta8_gray8; - Debug(2,"Delta: Using standard delta functions"); - } - } else { - /* CPU extensions disabled */ - fptr_delta8_rgba = &std_delta8_rgba; - fptr_delta8_bgra = &std_delta8_bgra; - fptr_delta8_argb = &std_delta8_argb; - fptr_delta8_abgr = &std_delta8_abgr; - fptr_delta8_gray8 = &std_delta8_gray8; - Debug(2,"Delta: CPU extensions disabled, using standard delta functions"); - } - - /* Use SSSE3 deinterlace functions? */ - if(config.cpu_extensions && sseversion >= 35) { - fptr_deinterlace_4field_rgba = &ssse3_deinterlace_4field_rgba; - fptr_deinterlace_4field_bgra = &ssse3_deinterlace_4field_bgra; - fptr_deinterlace_4field_argb = &ssse3_deinterlace_4field_argb; - fptr_deinterlace_4field_abgr = &ssse3_deinterlace_4field_abgr; - fptr_deinterlace_4field_gray8 = &ssse3_deinterlace_4field_gray8; - Debug(2,"Deinterlace: Using SSSE3 delta functions"); - } else { - fptr_deinterlace_4field_rgba = &std_deinterlace_4field_rgba; - fptr_deinterlace_4field_bgra = &std_deinterlace_4field_bgra; - fptr_deinterlace_4field_argb = &std_deinterlace_4field_argb; - fptr_deinterlace_4field_abgr = &std_deinterlace_4field_abgr; - fptr_deinterlace_4field_gray8 = &std_deinterlace_4field_gray8; - Debug(2,"Deinterlace: Using standard delta functions"); - } - - /* Use SSE2 aligned memory copy? */ - if(config.cpu_extensions && sseversion >= 20) { - fptr_imgbufcpy = &sse2_aligned_memcpy; - Debug(2,"Image buffer copy: Using SSE2 aligned memcpy"); - } else { - fptr_imgbufcpy = &memcpy; - Debug(2,"Image buffer copy: Using standard memcpy"); - } - - /* Code below relocated from zm_local_camera */ - Debug( 3, "Setting up static colour tables" ); - - y_table = new unsigned char[256]; - for ( int i = 0; i <= 255; i++ ) - { - unsigned char c = i; - if ( c <= 16 ) - y_table[c] = 0; - else if ( c >= 235 ) - y_table[c] = 255; - else - y_table[c] = (255*(c-16))/219; - } + /* Assign the blend pointer to function */ + if(config.fast_image_blends) { + if(config.cpu_extensions && sseversion >= 20) { + fptr_blend = &sse2_fastblend; /* SSE2 fast blend */ + Debug(2,"Blend: Using SSE2 fast blend function"); + } else { + fptr_blend = &std_fastblend; /* standard fast blend */ + Debug(2,"Blend: Using fast blend function"); + } + } else { + fptr_blend = &std_blend; + Debug(2,"Blend: Using standard blend function"); + } + + __attribute__((aligned(16))) uint8_t blend1[16] = {142,255,159,91,88,227,0,52,37,80,152,97,104,252,90,82}; + __attribute__((aligned(16))) uint8_t blend2[16] = {129,56,136,96,119,149,94,29,96,176,1,144,230,203,111,172}; + __attribute__((aligned(16))) uint8_t blendres[16]; + __attribute__((aligned(16))) uint8_t blendexp[16] = {141,231,157,92,91,217,11,49,45,92,133,103,119,246,92,93}; /* Expected results for 12.5% blend */ + + (*fptr_blend)(blend1,blend2,blendres,16,12.5); + + /* Compare results with expected results */ + for(int i=0;i<16;i++) { + if(abs(blendexp[i] - blendres[i]) > 3) { + Panic("Blend function failed self-test: Results differ from the expected results"); + } + } + + fptr_delta8_rgb = &std_delta8_rgb; + fptr_delta8_bgr = &std_delta8_bgr; + + /* Assign the delta functions */ + if(config.cpu_extensions) { + if(sseversion >= 35) { + /* SSSE3 available */ + fptr_delta8_rgba = &ssse3_delta8_rgba; + fptr_delta8_bgra = &ssse3_delta8_bgra; + fptr_delta8_argb = &ssse3_delta8_argb; + fptr_delta8_abgr = &ssse3_delta8_abgr; + fptr_delta8_gray8 = &sse2_delta8_gray8; + Debug(2,"Delta: Using SSSE3 delta functions"); + } else if(sseversion >= 20) { + /* SSE2 available */ + fptr_delta8_rgba = &sse2_delta8_rgba; + fptr_delta8_bgra = &sse2_delta8_bgra; + fptr_delta8_argb = &sse2_delta8_argb; + fptr_delta8_abgr = &sse2_delta8_abgr; + /* + ** On some systems, the 4 SSE2 algorithms above might be a little slower than + ** the standard algorithms, especially on early Pentium 4 processors. + ** In that case, comment out the 4 lines above and uncomment the 4 lines below + */ + // fptr_delta8_rgba = &std_delta8_rgba; + // fptr_delta8_bgra = &std_delta8_bgra; + // fptr_delta8_argb = &std_delta8_argb; + // fptr_delta8_abgr = &std_delta8_abgr; + fptr_delta8_gray8 = &sse2_delta8_gray8; + Debug(2,"Delta: Using SSE2 delta functions"); + } else { + /* No suitable SSE version available */ + fptr_delta8_rgba = &std_delta8_rgba; + fptr_delta8_bgra = &std_delta8_bgra; + fptr_delta8_argb = &std_delta8_argb; + fptr_delta8_abgr = &std_delta8_abgr; + fptr_delta8_gray8 = &std_delta8_gray8; + Debug(2,"Delta: Using standard delta functions"); + } + } else { + /* CPU extensions disabled */ + fptr_delta8_rgba = &std_delta8_rgba; + fptr_delta8_bgra = &std_delta8_bgra; + fptr_delta8_argb = &std_delta8_argb; + fptr_delta8_abgr = &std_delta8_abgr; + fptr_delta8_gray8 = &std_delta8_gray8; + Debug(2,"Delta: CPU extensions disabled, using standard delta functions"); + } + + /* Use SSSE3 deinterlace functions? */ + if(config.cpu_extensions && sseversion >= 35) { + fptr_deinterlace_4field_rgba = &ssse3_deinterlace_4field_rgba; + fptr_deinterlace_4field_bgra = &ssse3_deinterlace_4field_bgra; + fptr_deinterlace_4field_argb = &ssse3_deinterlace_4field_argb; + fptr_deinterlace_4field_abgr = &ssse3_deinterlace_4field_abgr; + fptr_deinterlace_4field_gray8 = &ssse3_deinterlace_4field_gray8; + Debug(2,"Deinterlace: Using SSSE3 delta functions"); + } else { + fptr_deinterlace_4field_rgba = &std_deinterlace_4field_rgba; + fptr_deinterlace_4field_bgra = &std_deinterlace_4field_bgra; + fptr_deinterlace_4field_argb = &std_deinterlace_4field_argb; + fptr_deinterlace_4field_abgr = &std_deinterlace_4field_abgr; + fptr_deinterlace_4field_gray8 = &std_deinterlace_4field_gray8; + Debug(2,"Deinterlace: Using standard delta functions"); + } + + /* Use SSE2 aligned memory copy? */ + if(config.cpu_extensions && sseversion >= 20) { + fptr_imgbufcpy = &sse2_aligned_memcpy; + Debug(2,"Image buffer copy: Using SSE2 aligned memcpy"); + } else { + fptr_imgbufcpy = &memcpy; + Debug(2,"Image buffer copy: Using standard memcpy"); + } + + /* Code below relocated from zm_local_camera */ + Debug( 3, "Setting up static colour tables" ); + + y_table = new unsigned char[256]; + for ( int i = 0; i <= 255; i++ ) + { + unsigned char c = i; + if ( c <= 16 ) + y_table[c] = 0; + else if ( c >= 235 ) + y_table[c] = 255; + else + y_table[c] = (255*(c-16))/219; + } - uv_table = new signed char[256]; - for ( int i = 0; i <= 255; i++ ) - { - unsigned char c = i; - if ( c <= 16 ) - uv_table[c] = -127; - else if ( c >= 240 ) - uv_table[c] = 127; - else - uv_table[c] = (127*(c-128))/112; - } + uv_table = new signed char[256]; + for ( int i = 0; i <= 255; i++ ) + { + unsigned char c = i; + if ( c <= 16 ) + uv_table[c] = -127; + else if ( c >= 240 ) + uv_table[c] = 127; + else + uv_table[c] = (127*(c-128))/112; + } - r_v_table = new short[255]; - g_v_table = new short[255]; - g_u_table = new short[255]; - b_u_table = new short[255]; - for ( int i = 0; i < 255; i++ ) - { - r_v_table[i] = (1402*(i-128))/1000; - g_u_table[i] = (344*(i-128))/1000; - g_v_table[i] = (714*(i-128))/1000; - b_u_table[i] = (1772*(i-128))/1000; - } - - initialised = true; + r_v_table = new short[255]; + g_v_table = new short[255]; + g_u_table = new short[255]; + b_u_table = new short[255]; + for ( int i = 0; i < 255; i++ ) + { + r_v_table[i] = (1402*(i-128))/1000; + g_u_table[i] = (344*(i-128))/1000; + g_v_table[i] = (714*(i-128))/1000; + b_u_table[i] = (1772*(i-128))/1000; + } + + initialised = true; } /* 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) { - unsigned int newsize; + unsigned int newsize; - 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; - } - - if(!p_height || !p_width) { - Error("WriteBuffer called with invaid width or height: %d %d",p_width,p_height); - return NULL; - } - - if(p_width != width || p_height != height || p_colours != colours || p_subpixelorder != subpixelorder) { - newsize = (p_width * p_height) * p_colours; - - if(buffer == NULL) { - AllocImgBuffer(newsize); - } else { - if(allocation < newsize) { - if(holdbuffer) { - Error("Held buffer is undersized for requested buffer"); - return NULL; - } else { - /* Replace buffer with a bigger one */ - //DumpImgBuffer(); // Done in AllocImgBuffer too - AllocImgBuffer(newsize); - } - } - } - - width = p_width; - height = p_height; - colours = p_colours; - subpixelorder = p_subpixelorder; - pixels = height*width; - size = newsize; - } - - return buffer; + 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; + } + + if(!p_height || !p_width) { + Error("WriteBuffer called with invaid width or height: %d %d",p_width,p_height); + return NULL; + } + + if(p_width != width || p_height != height || p_colours != colours || p_subpixelorder != subpixelorder) { + newsize = (p_width * p_height) * p_colours; + + if(buffer == NULL) { + AllocImgBuffer(newsize); + } else { + if(allocation < newsize) { + if(holdbuffer) { + Error("Held buffer is undersized for requested buffer"); + return NULL; + } else { + /* Replace buffer with a bigger one */ + //DumpImgBuffer(); // Done in AllocImgBuffer too + AllocImgBuffer(newsize); + } + } + } + + width = p_width; + height = p_height; + colours = p_colours; + subpixelorder = p_subpixelorder; + pixels = height*width; + size = newsize; + } + + return buffer; } /* Assign an existing buffer to the image instead of copying from a source buffer. The goal is to reduce the amount of memory copying and increase efficiency and buffer reusing. */ void Image::AssignDirect( const unsigned int p_width, const unsigned int p_height, const unsigned int p_colours, const unsigned int p_subpixelorder, uint8_t *new_buffer, const size_t buffer_size, const int p_buffertype) { - if(new_buffer == NULL) { - Error("Attempt to directly assign buffer from a NULL pointer"); - return; - } + if(new_buffer == NULL) { + Error("Attempt to directly assign buffer from a NULL pointer"); + return; + } - if(!p_height || !p_width) { - Error("Attempt to directly assign buffer with invalid width or height: %d %d",p_width,p_height); - return; - } + if(!p_height || !p_width) { + Error("Attempt to directly assign buffer with invalid width or height: %d %d",p_width,p_height); + return; + } - if(p_colours != ZM_COLOUR_GRAY8 && p_colours != ZM_COLOUR_RGB24 && p_colours != ZM_COLOUR_RGB32) { - Error("Attempt to directly assign buffer with unexpected colours per pixel: %d",p_colours); - return; - } + if(p_colours != ZM_COLOUR_GRAY8 && p_colours != ZM_COLOUR_RGB24 && p_colours != ZM_COLOUR_RGB32) { + Error("Attempt to directly assign buffer with unexpected colours per pixel: %d",p_colours); + return; + } - unsigned int new_buffer_size = ((p_width*p_height)*p_colours); - - if(buffer_size < new_buffer_size) { - Error("Attempt to directly assign buffer from an undersized buffer of size: %zu, needed %dx%d*%d colours = %zu",buffer_size, p_width, p_height, p_colours, new_buffer_size ); - return; - } - - if(holdbuffer && buffer) { - if(new_buffer_size > allocation) { - Error("Held buffer is undersized for assigned buffer"); - return; - } else { - width = p_width; - height = p_height; - colours = p_colours; - subpixelorder = p_subpixelorder; - pixels = height*width; - size = new_buffer_size; // was pixels*colours, but we already calculated it above as new_buffer_size - - /* Copy into the held buffer */ - if(new_buffer != buffer) - (*fptr_imgbufcpy)(buffer, new_buffer, size); - - /* Free the new buffer */ - DumpBuffer(new_buffer, p_buffertype); - } - } else { - /* Free an existing buffer if any */ - DumpImgBuffer(); - - width = p_width; - height = p_height; - colours = p_colours; - subpixelorder = p_subpixelorder; - pixels = height*width; - size = new_buffer_size; // was pixels*colours, but we already calculated it above as new_buffer_size - - allocation = buffer_size; - buffertype = p_buffertype; - buffer = new_buffer; - } - + unsigned int new_buffer_size = ((p_width*p_height)*p_colours); + + if(buffer_size < new_buffer_size) { + Error("Attempt to directly assign buffer from an undersized buffer of size: %zu, needed %dx%d*%d colours = %zu",buffer_size, p_width, p_height, p_colours, new_buffer_size ); + return; + } + + if(holdbuffer && buffer) { + if(new_buffer_size > allocation) { + Error("Held buffer is undersized for assigned buffer"); + return; + } else { + width = p_width; + height = p_height; + colours = p_colours; + subpixelorder = p_subpixelorder; + pixels = height*width; + size = new_buffer_size; // was pixels*colours, but we already calculated it above as new_buffer_size + + /* Copy into the held buffer */ + if(new_buffer != buffer) + (*fptr_imgbufcpy)(buffer, new_buffer, size); + + /* Free the new buffer */ + DumpBuffer(new_buffer, p_buffertype); + } + } else { + /* Free an existing buffer if any */ + DumpImgBuffer(); + + width = p_width; + height = p_height; + colours = p_colours; + subpixelorder = p_subpixelorder; + pixels = height*width; + size = new_buffer_size; // was pixels*colours, but we already calculated it above as new_buffer_size + + allocation = buffer_size; + buffertype = p_buffertype; + buffer = new_buffer; + } + } 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; + unsigned int new_size = (p_width * p_height) * p_colours; - if(new_buffer == NULL) { - Error("Attempt to assign buffer from a NULL pointer"); - return; - } - - if(buffer_size < new_size) { - Error("Attempt to assign buffer from an undersized buffer of size: %zu",buffer_size); - return; - } - - if(!p_height || !p_width) { - Error("Attempt to assign buffer with invalid width or height: %d %d",p_width,p_height); - return; - } - - if(p_colours != ZM_COLOUR_GRAY8 && p_colours != ZM_COLOUR_RGB24 && p_colours != ZM_COLOUR_RGB32) { - Error("Attempt to assign buffer with unexpected colours per pixel: %d",p_colours); - return; - } - - if ( !buffer || p_width != width || p_height != height || p_colours != colours || p_subpixelorder != subpixelorder) { + if(new_buffer == NULL) { + Error("Attempt to assign buffer from a NULL pointer"); + return; + } + + if(buffer_size < new_size) { + Error("Attempt to assign buffer from an undersized buffer of size: %zu",buffer_size); + return; + } + + if(!p_height || !p_width) { + Error("Attempt to assign buffer with invalid width or height: %d %d",p_width,p_height); + return; + } + + if(p_colours != ZM_COLOUR_GRAY8 && p_colours != ZM_COLOUR_RGB24 && p_colours != ZM_COLOUR_RGB32) { + Error("Attempt to assign buffer with unexpected colours per pixel: %d",p_colours); + return; + } + + if ( !buffer || p_width != width || p_height != height || p_colours != colours || p_subpixelorder != subpixelorder) { - if (holdbuffer && buffer) { - if (new_size > allocation) { - Error("Held buffer is undersized for assigned buffer"); - return; - } - } else { - if(new_size > allocation || !buffer) { - DumpImgBuffer(); - AllocImgBuffer(new_size); - } - } - - width = p_width; - height = p_height; - pixels = width*height; - colours = p_colours; - subpixelorder = p_subpixelorder; - size = new_size; - } - - if(new_buffer != buffer) - (*fptr_imgbufcpy)(buffer, new_buffer, size); - + if (holdbuffer && buffer) { + if (new_size > allocation) { + Error("Held buffer is undersized for assigned buffer"); + return; + } + } else { + if(new_size > allocation || !buffer) { + DumpImgBuffer(); + AllocImgBuffer(new_size); + } + } + + width = p_width; + height = p_height; + pixels = width*height; + colours = p_colours; + subpixelorder = p_subpixelorder; + size = new_size; + } + + if(new_buffer != buffer) + (*fptr_imgbufcpy)(buffer, new_buffer, size); + } void Image::Assign( const Image &image ) { - unsigned int new_size = (image.width * image.height) * image.colours; - - if(image.buffer == NULL) { - Error("Attempt to assign image with an empty buffer"); - return; - } + unsigned int new_size = (image.width * image.height) * 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(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); + return; + } + + if ( !buffer || image.width != width || image.height != height || image.colours != colours || image.subpixelorder != subpixelorder) { - if (holdbuffer && buffer) { - if (new_size > allocation) { - Error("Held buffer is undersized for assigned buffer"); - return; - } - } else { - if(new_size > allocation || !buffer) { - // DumpImgBuffer(); This is also done in AllocImgBuffer - AllocImgBuffer(new_size); - } - } - - width = image.width; - height = image.height; - pixels = width*height; - colours = image.colours; - subpixelorder = image.subpixelorder; - size = new_size; - } - - if(image.buffer != buffer) - (*fptr_imgbufcpy)(buffer, image.buffer, size); + if (holdbuffer && buffer) { + if (new_size > allocation) { + Error("Held buffer is undersized for assigned buffer"); + return; + } + } else { + if(new_size > allocation || !buffer) { + // DumpImgBuffer(); This is also done in AllocImgBuffer + AllocImgBuffer(new_size); + } + } + + width = image.width; + height = image.height; + pixels = width*height; + colours = image.colours; + subpixelorder = image.subpixelorder; + size = new_size; + } + + 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 ) { - if ( colours != ZM_COLOUR_GRAY8 ) - { - Panic( "Attempt to highlight image edges when colours = %d", colours ); - } - - /* Convert the colour's RGBA subpixel order into the image's subpixel order */ - 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 ); - uint8_t* high_buff = high_image->WriteBuffer(width, height, p_colours, p_subpixelorder); - - /* Set image to all black */ - high_image->Clear(); + if ( colours != ZM_COLOUR_GRAY8 ) + { + Panic( "Attempt to highlight image edges when colours = %d", colours ); + } + + /* Convert the colour's RGBA subpixel order into the image's subpixel order */ + 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 ); + uint8_t* high_buff = high_image->WriteBuffer(width, height, p_colours, p_subpixelorder); + + /* Set image to all black */ + high_image->Clear(); - unsigned int lo_x = limits?limits->Lo().X():0; - unsigned int lo_y = limits?limits->Lo().Y():0; - unsigned int hi_x = limits?limits->Hi().X():width-1; - unsigned int hi_y = limits?limits->Hi().Y():height-1; - - if ( p_colours == ZM_COLOUR_GRAY8 ) - { - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - const uint8_t* p = buffer + (y * width) + lo_x; - uint8_t* phigh = high_buff + (y * width) + lo_x; - for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ ) - { - bool edge = false; - if ( *p ) - { - 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; - } - if ( edge ) - { - *phigh = colour; - } - } - } - } - else if ( p_colours == ZM_COLOUR_RGB24 ) - { - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - const uint8_t* p = buffer + (y * width) + lo_x; - uint8_t* phigh = high_buff + (((y * width) + lo_x) * 3); - for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh += 3 ) - { - bool edge = false; - if ( *p ) - { - 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; - } - if ( edge ) - { - RED_PTR_RGBA(phigh) = RED_VAL_RGBA(colour); - GREEN_PTR_RGBA(phigh) = GREEN_VAL_RGBA(colour); - BLUE_PTR_RGBA(phigh) = BLUE_VAL_RGBA(colour); - } - } - } - } - else if ( p_colours == ZM_COLOUR_RGB32 ) - { - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - const uint8_t* p = buffer + (y * width) + lo_x; - Rgb* phigh = (Rgb*)(high_buff + (((y * width) + lo_x) * 4)); - for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ ) - { - bool edge = false; - if ( *p ) - { - 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; - } - if ( edge ) - { - *phigh = colour; - } - } - } - } - - return( high_image ); + unsigned int lo_x = limits?limits->Lo().X():0; + unsigned int lo_y = limits?limits->Lo().Y():0; + unsigned int hi_x = limits?limits->Hi().X():width-1; + unsigned int hi_y = limits?limits->Hi().Y():height-1; + + if ( p_colours == ZM_COLOUR_GRAY8 ) + { + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + const uint8_t* p = buffer + (y * width) + lo_x; + uint8_t* phigh = high_buff + (y * width) + lo_x; + for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ ) + { + bool edge = false; + if ( *p ) + { + 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; + } + if ( edge ) + { + *phigh = colour; + } + } + } + } + else if ( p_colours == ZM_COLOUR_RGB24 ) + { + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + const uint8_t* p = buffer + (y * width) + lo_x; + uint8_t* phigh = high_buff + (((y * width) + lo_x) * 3); + for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh += 3 ) + { + bool edge = false; + if ( *p ) + { + 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; + } + if ( edge ) + { + RED_PTR_RGBA(phigh) = RED_VAL_RGBA(colour); + GREEN_PTR_RGBA(phigh) = GREEN_VAL_RGBA(colour); + BLUE_PTR_RGBA(phigh) = BLUE_VAL_RGBA(colour); + } + } + } + } + else if ( p_colours == ZM_COLOUR_RGB32 ) + { + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + const uint8_t* p = buffer + (y * width) + lo_x; + Rgb* phigh = (Rgb*)(high_buff + (((y * width) + lo_x) * 4)); + for ( unsigned int x = lo_x; x <= hi_x; x++, p++, phigh++ ) + { + bool edge = false; + if ( *p ) + { + 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; + } + if ( edge ) + { + *phigh = colour; + } + } + } + } + + return( high_image ); } bool Image::ReadRaw( const char *filename ) { - FILE *infile; - if ( (infile = fopen( filename, "rb" )) == NULL ) - { - Error( "Can't open %s: %s", filename, strerror(errno) ); - return( false ); - } + FILE *infile; + if ( (infile = fopen( filename, "rb" )) == NULL ) + { + Error( "Can't open %s: %s", filename, strerror(errno) ); + return( false ); + } - struct stat statbuf; - if ( fstat( fileno(infile), &statbuf ) < 0 ) - { - Error( "Can't fstat %s: %s", filename, strerror(errno) ); - return( false ); - } + struct stat statbuf; + if ( fstat( fileno(infile), &statbuf ) < 0 ) + { + Error( "Can't fstat %s: %s", filename, strerror(errno) ); + return( false ); + } - if ( statbuf.st_size != size ) - { - Error( "Raw file size mismatch, expected %d bytes, found %ld", size, statbuf.st_size ); - return( false ); - } + if ( statbuf.st_size != size ) + { + Error( "Raw file size mismatch, expected %d bytes, found %ld", size, statbuf.st_size ); + return( false ); + } - if ( fread( buffer, size, 1, infile ) < 1 ) - { - Fatal( "Unable to read from '%s': %s", filename, strerror(errno) ); - return( false ); - } + if ( fread( buffer, size, 1, infile ) < 1 ) + { + Fatal( "Unable to read from '%s': %s", filename, strerror(errno) ); + return( false ); + } - fclose( infile ); + fclose( infile ); - return( true ); + return( true ); } bool Image::WriteRaw( const char *filename ) const { - FILE *outfile; - if ( (outfile = fopen( filename, "wb" )) == NULL ) - { - Error( "Can't open %s: %s", filename, strerror(errno) ); - return( false ); - } + FILE *outfile; + if ( (outfile = fopen( filename, "wb" )) == NULL ) + { + Error( "Can't open %s: %s", filename, strerror(errno) ); + return( false ); + } - if ( fwrite( buffer, size, 1, outfile ) != 1 ) - { - Error( "Unable to write to '%s': %s", filename, strerror(errno) ); - return( false ); - } + if ( fwrite( buffer, size, 1, outfile ) != 1 ) + { + Error( "Unable to write to '%s': %s", filename, strerror(errno) ); + return( false ); + } - fclose( outfile ); + fclose( outfile ); - return( true ); + return( true ); } bool Image::ReadJpeg( const char *filename, unsigned int p_colours, unsigned int p_subpixelorder) { - unsigned int new_width, new_height, new_colours, new_subpixelorder; - struct jpeg_decompress_struct *cinfo = jpg_dcinfo; + unsigned int new_width, new_height, new_colours, new_subpixelorder; + struct jpeg_decompress_struct *cinfo = jpg_dcinfo; - if ( !cinfo ) - { - cinfo = jpg_dcinfo = new jpeg_decompress_struct; - cinfo->err = jpeg_std_error( &jpg_err.pub ); - jpg_err.pub.error_exit = zm_jpeg_error_exit; - jpg_err.pub.emit_message = zm_jpeg_emit_message; - jpeg_create_decompress( cinfo ); - } + if ( !cinfo ) + { + cinfo = jpg_dcinfo = new jpeg_decompress_struct; + cinfo->err = jpeg_std_error( &jpg_err.pub ); + jpg_err.pub.error_exit = zm_jpeg_error_exit; + jpg_err.pub.emit_message = zm_jpeg_emit_message; + jpeg_create_decompress( cinfo ); + } - FILE *infile; - if ( (infile = fopen( filename, "rb" )) == NULL ) - { - Error( "Can't open %s: %s", filename, strerror(errno) ); - return( false ); - } + FILE *infile; + if ( (infile = fopen( filename, "rb" )) == NULL ) + { + Error( "Can't open %s: %s", filename, strerror(errno) ); + return( false ); + } - if ( setjmp( jpg_err.setjmp_buffer ) ) - { - jpeg_abort_decompress( cinfo ); - fclose( infile ); - return( false ); - } + if ( setjmp( jpg_err.setjmp_buffer ) ) + { + jpeg_abort_decompress( cinfo ); + fclose( infile ); + return( false ); + } - jpeg_stdio_src( cinfo, infile ); + jpeg_stdio_src( cinfo, infile ); - jpeg_read_header( cinfo, TRUE ); + jpeg_read_header( cinfo, TRUE ); - if ( cinfo->num_components != 1 && cinfo->num_components != 3 ) - { - Error( "Unexpected colours when reading jpeg image: %d", colours ); - jpeg_abort_decompress( cinfo ); - fclose( infile ); - return( false ); - } - - /* Check if the image has at least one huffman table defined. If not, use the standard ones */ - /* This is required for the MJPEG capture palette of USB devices */ - if(cinfo->dc_huff_tbl_ptrs[0] == NULL) { - zm_use_std_huff_tables(cinfo); - } + if ( cinfo->num_components != 1 && cinfo->num_components != 3 ) + { + Error( "Unexpected colours when reading jpeg image: %d", colours ); + jpeg_abort_decompress( cinfo ); + fclose( infile ); + return( false ); + } + + /* Check if the image has at least one huffman table defined. If not, use the standard ones */ + /* This is required for the MJPEG capture palette of USB devices */ + if(cinfo->dc_huff_tbl_ptrs[0] == NULL) { + zm_use_std_huff_tables(cinfo); + } - new_width = cinfo->image_width; - new_height = cinfo->image_height; + new_width = cinfo->image_width; + new_height = cinfo->image_height; - if ( width != new_width || height != new_height ) - { - Debug(9,"Image dimensions differ. Old: %ux%u New: %ux%u",width,height,new_width,new_height); - } - - switch(p_colours) { - case ZM_COLOUR_GRAY8: - { - cinfo->out_color_space = JCS_GRAYSCALE; - new_colours = ZM_COLOUR_GRAY8; - new_subpixelorder = ZM_SUBPIX_ORDER_NONE; - break; - } - case ZM_COLOUR_RGB32: - { + if ( width != new_width || height != new_height ) + { + Debug(9,"Image dimensions differ. Old: %ux%u New: %ux%u",width,height,new_width,new_height); + } + + switch(p_colours) { + case ZM_COLOUR_GRAY8: + { + cinfo->out_color_space = JCS_GRAYSCALE; + new_colours = ZM_COLOUR_GRAY8; + new_subpixelorder = ZM_SUBPIX_ORDER_NONE; + break; + } + case ZM_COLOUR_RGB32: + { #ifdef JCS_EXTENSIONS - new_colours = ZM_COLOUR_RGB32; - if(p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) { - cinfo->out_color_space = JCS_EXT_BGRX; - new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; - } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) { - cinfo->out_color_space = JCS_EXT_XRGB; - new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; - } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) { - cinfo->out_color_space = JCS_EXT_XBGR; - new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; - } else { - /* Assume RGBA */ - cinfo->out_color_space = JCS_EXT_RGBX; - new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; - } - break; + new_colours = ZM_COLOUR_RGB32; + if(p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + cinfo->out_color_space = JCS_EXT_BGRX; + new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; + } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + cinfo->out_color_space = JCS_EXT_XRGB; + new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; + } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + cinfo->out_color_space = JCS_EXT_XBGR; + new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; + } else { + /* Assume RGBA */ + cinfo->out_color_space = JCS_EXT_RGBX; + new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; + } + break; #else - Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead."); + Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead."); #endif - } - case ZM_COLOUR_RGB24: - default: - { - new_colours = ZM_COLOUR_RGB24; - if(p_subpixelorder == ZM_SUBPIX_ORDER_BGR) { -#ifdef JCS_EXTENSIONS - cinfo->out_color_space = JCS_EXT_BGR; - new_subpixelorder = ZM_SUBPIX_ORDER_BGR; + } + case ZM_COLOUR_RGB24: + default: + { + new_colours = ZM_COLOUR_RGB24; + if(p_subpixelorder == ZM_SUBPIX_ORDER_BGR) { +#ifdef JCS_EXTENSIONS + cinfo->out_color_space = JCS_EXT_BGR; + new_subpixelorder = ZM_SUBPIX_ORDER_BGR; #else - Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); - cinfo->out_color_space = JCS_RGB; - new_subpixelorder = ZM_SUBPIX_ORDER_RGB; + Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); + cinfo->out_color_space = JCS_RGB; + new_subpixelorder = ZM_SUBPIX_ORDER_RGB; #endif - } else { - /* Assume RGB */ + } else { + /* Assume RGB */ /* #ifdef JCS_EXTENSIONS - cinfo->out_color_space = JCS_EXT_RGB; + cinfo->out_color_space = JCS_EXT_RGB; #else - cinfo->out_color_space = JCS_RGB; + cinfo->out_color_space = JCS_RGB; #endif */ - cinfo->out_color_space = JCS_RGB; - new_subpixelorder = ZM_SUBPIX_ORDER_RGB; - } - break; - } - } - - if(WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL) { - Error("Failed requesting writeable buffer for reading JPEG image."); - jpeg_abort_decompress( cinfo ); - fclose( infile ); - return( false ); - } + cinfo->out_color_space = JCS_RGB; + new_subpixelorder = ZM_SUBPIX_ORDER_RGB; + } + break; + } + } + + if(WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL) { + Error("Failed requesting writeable buffer for reading JPEG image."); + jpeg_abort_decompress( cinfo ); + fclose( infile ); + return( false ); + } - jpeg_start_decompress( cinfo ); + jpeg_start_decompress( cinfo ); - JSAMPROW row_pointer; /* pointer to a single row */ - int row_stride = width * colours; /* physical row width in buffer */ - while ( cinfo->output_scanline < cinfo->output_height ) - { - row_pointer = &buffer[cinfo->output_scanline * row_stride]; - jpeg_read_scanlines( cinfo, &row_pointer, 1 ); - } + JSAMPROW row_pointer; /* pointer to a single row */ + int row_stride = width * colours; /* physical row width in buffer */ + while ( cinfo->output_scanline < cinfo->output_height ) + { + row_pointer = &buffer[cinfo->output_scanline * row_stride]; + jpeg_read_scanlines( cinfo, &row_pointer, 1 ); + } - jpeg_finish_decompress( cinfo ); + jpeg_finish_decompress( cinfo ); - fclose( infile ); + fclose( infile ); - return( true ); + return( true ); } // Multiple calling formats to permit inclusion (or not) of both quality_override and timestamp (exif), with suitable defaults. @@ -793,2326 +793,2326 @@ bool Image::ReadJpeg( const char *filename, unsigned int p_colours, unsigned int bool Image::WriteJpeg( const char *filename, int quality_override) const { - return Image::WriteJpeg(filename, quality_override, (timeval){0,0}); + return Image::WriteJpeg(filename, quality_override, (timeval){0,0}); } bool Image::WriteJpeg( const char *filename) const { - return Image::WriteJpeg(filename, 0, (timeval){0,0}); + return Image::WriteJpeg(filename, 0, (timeval){0,0}); } bool Image::WriteJpeg( const char *filename, struct timeval timestamp ) const { - return Image::WriteJpeg(filename,0,timestamp); + return Image::WriteJpeg(filename,0,timestamp); } bool Image::WriteJpeg( const char *filename, int quality_override, struct timeval timestamp ) const { - if ( config.colour_jpeg_files && colours == ZM_COLOUR_GRAY8 ) - { - Image temp_image( *this ); - temp_image.Colourise( ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB ); - return( temp_image.WriteJpeg( filename, quality_override, timestamp) ); - } - int quality = quality_override?quality_override:config.jpeg_file_quality; + if ( config.colour_jpeg_files && colours == ZM_COLOUR_GRAY8 ) + { + Image temp_image( *this ); + temp_image.Colourise( ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB ); + return( temp_image.WriteJpeg( filename, quality_override, timestamp) ); + } + int quality = quality_override?quality_override:config.jpeg_file_quality; - struct jpeg_compress_struct *cinfo = jpg_ccinfo[quality]; + struct jpeg_compress_struct *cinfo = jpg_ccinfo[quality]; - if ( !cinfo ) - { - cinfo = jpg_ccinfo[quality] = new jpeg_compress_struct; - cinfo->err = jpeg_std_error( &jpg_err.pub ); - jpg_err.pub.error_exit = zm_jpeg_error_exit; - jpg_err.pub.emit_message = zm_jpeg_emit_message; - jpeg_create_compress( cinfo ); - } + if ( !cinfo ) + { + cinfo = jpg_ccinfo[quality] = new jpeg_compress_struct; + cinfo->err = jpeg_std_error( &jpg_err.pub ); + jpg_err.pub.error_exit = zm_jpeg_error_exit; + jpg_err.pub.emit_message = zm_jpeg_emit_message; + jpeg_create_compress( cinfo ); + } - FILE *outfile; - if ( (outfile = fopen( filename, "wb" )) == NULL ) - { - Error( "Can't open %s: %s", filename, strerror(errno) ); - return( false ); - } - jpeg_stdio_dest( cinfo, outfile ); + FILE *outfile; + if ( (outfile = fopen( filename, "wb" )) == NULL ) + { + Error( "Can't open %s: %s", filename, strerror(errno) ); + return( false ); + } + jpeg_stdio_dest( cinfo, outfile ); - cinfo->image_width = width; /* image width and height, in pixels */ - cinfo->image_height = height; - - switch(colours) { - case ZM_COLOUR_GRAY8: - { - cinfo->input_components = 1; - cinfo->in_color_space = JCS_GRAYSCALE; - break; - } - case ZM_COLOUR_RGB32: - { + cinfo->image_width = width; /* image width and height, in pixels */ + cinfo->image_height = height; + + switch(colours) { + case ZM_COLOUR_GRAY8: + { + cinfo->input_components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; + break; + } + case ZM_COLOUR_RGB32: + { #ifdef JCS_EXTENSIONS - cinfo->input_components = 4; - if(subpixelorder == ZM_SUBPIX_ORDER_BGRA) { - cinfo->in_color_space = JCS_EXT_BGRX; - } else if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) { - cinfo->in_color_space = JCS_EXT_XRGB; - } else if(subpixelorder == ZM_SUBPIX_ORDER_ABGR) { - cinfo->in_color_space = JCS_EXT_XBGR; - } else { - /* Assume RGBA */ - cinfo->in_color_space = JCS_EXT_RGBX; - } + cinfo->input_components = 4; + if(subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + cinfo->in_color_space = JCS_EXT_BGRX; + } else if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + cinfo->in_color_space = JCS_EXT_XRGB; + } else if(subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + cinfo->in_color_space = JCS_EXT_XBGR; + } else { + /* Assume RGBA */ + cinfo->in_color_space = JCS_EXT_RGBX; + } #else - Error("libjpeg-turbo is required for JPEG encoding directly from RGB32 source"); - jpeg_abort_compress( cinfo ); - fclose(outfile); - return(false); + Error("libjpeg-turbo is required for JPEG encoding directly from RGB32 source"); + jpeg_abort_compress( cinfo ); + fclose(outfile); + return(false); #endif - break; - } - case ZM_COLOUR_RGB24: - default: - { - cinfo->input_components = 3; - if(subpixelorder == ZM_SUBPIX_ORDER_BGR) { + break; + } + case ZM_COLOUR_RGB24: + default: + { + cinfo->input_components = 3; + if(subpixelorder == ZM_SUBPIX_ORDER_BGR) { #ifdef JCS_EXTENSIONS - cinfo->in_color_space = JCS_EXT_BGR; + cinfo->in_color_space = JCS_EXT_BGR; #else - Error("libjpeg-turbo is required for JPEG encoding directly from BGR24 source"); - jpeg_abort_compress( cinfo ); - fclose(outfile); - return(false); + Error("libjpeg-turbo is required for JPEG encoding directly from BGR24 source"); + jpeg_abort_compress( cinfo ); + fclose(outfile); + return(false); #endif - } else { - /* Assume RGB */ + } else { + /* Assume RGB */ /* #ifdef JCS_EXTENSIONS - cinfo->out_color_space = JCS_EXT_RGB; + cinfo->out_color_space = JCS_EXT_RGB; #else - cinfo->out_color_space = JCS_RGB; + cinfo->out_color_space = JCS_RGB; #endif */ - cinfo->in_color_space = JCS_RGB; - } - break; - } - } - - jpeg_set_defaults( cinfo ); - jpeg_set_quality( cinfo, quality, FALSE ); - cinfo->dct_method = JDCT_FASTEST; + cinfo->in_color_space = JCS_RGB; + } + break; + } + } + + jpeg_set_defaults( cinfo ); + jpeg_set_quality( cinfo, quality, FALSE ); + cinfo->dct_method = JDCT_FASTEST; - jpeg_start_compress( cinfo, TRUE ); - if ( config.add_jpeg_comments && text[0] ) - { - 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 - // No timestamp just leave off the exif section. - if(timestamp.tv_sec) - { - #define EXIFTIMES_MS_OFFSET 0x36 // three decimal digits for milliseconds - #define EXIFTIMES_MS_LEN 0x03 - #define EXIFTIMES_OFFSET 0x3E // 19 characters format '2015:07:21 13:14:45' not including quotes - #define EXIFTIMES_LEN 0x13 // = 19 - #define EXIF_CODE 0xE1 + jpeg_start_compress( cinfo, TRUE ); + if ( config.add_jpeg_comments && text[0] ) + { + 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 + // No timestamp just leave off the exif section. + if(timestamp.tv_sec) + { + #define EXIFTIMES_MS_OFFSET 0x36 // three decimal digits for milliseconds + #define EXIFTIMES_MS_LEN 0x03 + #define EXIFTIMES_OFFSET 0x3E // 19 characters format '2015:07:21 13:14:45' not including quotes + #define EXIFTIMES_LEN 0x13 // = 19 + #define EXIF_CODE 0xE1 - char timebuf[64], msbuf[64]; - 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 - unsigned char exiftimes[82] = { - 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x69, 0x87, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x03, 0x90, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x91, 0x92, - 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00 }; - memcpy(&exiftimes[EXIFTIMES_OFFSET], timebuf,EXIFTIMES_LEN); - memcpy(&exiftimes[EXIFTIMES_MS_OFFSET], msbuf ,EXIFTIMES_MS_LEN); - jpeg_write_marker (cinfo, EXIF_CODE, (const JOCTET *)exiftimes, sizeof(exiftimes) ); - } + char timebuf[64], msbuf[64]; + 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 + unsigned char exiftimes[82] = { + 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, 0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x69, 0x87, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x03, 0x90, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x91, 0x92, + 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00 }; + memcpy(&exiftimes[EXIFTIMES_OFFSET], timebuf,EXIFTIMES_LEN); + memcpy(&exiftimes[EXIFTIMES_MS_OFFSET], msbuf ,EXIFTIMES_MS_LEN); + jpeg_write_marker (cinfo, EXIF_CODE, (const JOCTET *)exiftimes, sizeof(exiftimes) ); + } - JSAMPROW row_pointer; /* pointer to a single row */ - int row_stride = cinfo->image_width * colours; /* physical row width in buffer */ - while ( cinfo->next_scanline < cinfo->image_height ) - { - row_pointer = &buffer[cinfo->next_scanline * row_stride]; - jpeg_write_scanlines( cinfo, &row_pointer, 1 ); - } + JSAMPROW row_pointer; /* pointer to a single row */ + int row_stride = cinfo->image_width * colours; /* physical row width in buffer */ + while ( cinfo->next_scanline < cinfo->image_height ) + { + row_pointer = &buffer[cinfo->next_scanline * row_stride]; + jpeg_write_scanlines( cinfo, &row_pointer, 1 ); + } - jpeg_finish_compress( cinfo ); + jpeg_finish_compress( cinfo ); - fclose( outfile ); + fclose( outfile ); - return( true ); + return( true ); } bool Image::DecodeJpeg( const JOCTET *inbuffer, int inbuffer_size, unsigned int p_colours, unsigned int p_subpixelorder) { - unsigned int new_width, new_height, new_colours, new_subpixelorder; - struct jpeg_decompress_struct *cinfo = jpg_dcinfo; + unsigned int new_width, new_height, new_colours, new_subpixelorder; + struct jpeg_decompress_struct *cinfo = jpg_dcinfo; - if ( !cinfo ) - { - cinfo = jpg_dcinfo = new jpeg_decompress_struct; - cinfo->err = jpeg_std_error( &jpg_err.pub ); - jpg_err.pub.error_exit = zm_jpeg_error_exit; - jpg_err.pub.emit_message = zm_jpeg_emit_message; - jpeg_create_decompress( cinfo ); - } + if ( !cinfo ) + { + cinfo = jpg_dcinfo = new jpeg_decompress_struct; + cinfo->err = jpeg_std_error( &jpg_err.pub ); + jpg_err.pub.error_exit = zm_jpeg_error_exit; + jpg_err.pub.emit_message = zm_jpeg_emit_message; + jpeg_create_decompress( cinfo ); + } - if ( setjmp( jpg_err.setjmp_buffer ) ) - { - jpeg_abort_decompress( cinfo ); - return( false ); - } + if ( setjmp( jpg_err.setjmp_buffer ) ) + { + jpeg_abort_decompress( cinfo ); + return( false ); + } - zm_jpeg_mem_src( cinfo, inbuffer, inbuffer_size ); + zm_jpeg_mem_src( cinfo, inbuffer, inbuffer_size ); - jpeg_read_header( cinfo, TRUE ); + jpeg_read_header( cinfo, TRUE ); - if ( cinfo->num_components != 1 && cinfo->num_components != 3 ) - { - Error( "Unexpected colours when reading jpeg image: %d", colours ); - jpeg_abort_decompress( cinfo ); - return( false ); - } - - /* Check if the image has at least one huffman table defined. If not, use the standard ones */ - /* This is required for the MJPEG capture palette of USB devices */ - if(cinfo->dc_huff_tbl_ptrs[0] == NULL) { - zm_use_std_huff_tables(cinfo); - } + if ( cinfo->num_components != 1 && cinfo->num_components != 3 ) + { + Error( "Unexpected colours when reading jpeg image: %d", colours ); + jpeg_abort_decompress( cinfo ); + return( false ); + } + + /* Check if the image has at least one huffman table defined. If not, use the standard ones */ + /* This is required for the MJPEG capture palette of USB devices */ + if(cinfo->dc_huff_tbl_ptrs[0] == NULL) { + zm_use_std_huff_tables(cinfo); + } - new_width = cinfo->image_width; - new_height = cinfo->image_height; + new_width = cinfo->image_width; + new_height = cinfo->image_height; - if ( width != new_width || height != new_height ) - { - Debug(9,"Image dimensions differ. Old: %ux%u New: %ux%u",width,height,new_width,new_height); - } - - switch(p_colours) { - case ZM_COLOUR_GRAY8: - { - cinfo->out_color_space = JCS_GRAYSCALE; - new_colours = ZM_COLOUR_GRAY8; - new_subpixelorder = ZM_SUBPIX_ORDER_NONE; - break; - } - case ZM_COLOUR_RGB32: - { + if ( width != new_width || height != new_height ) + { + Debug(9,"Image dimensions differ. Old: %ux%u New: %ux%u",width,height,new_width,new_height); + } + + switch(p_colours) { + case ZM_COLOUR_GRAY8: + { + cinfo->out_color_space = JCS_GRAYSCALE; + new_colours = ZM_COLOUR_GRAY8; + new_subpixelorder = ZM_SUBPIX_ORDER_NONE; + break; + } + case ZM_COLOUR_RGB32: + { #ifdef JCS_EXTENSIONS - new_colours = ZM_COLOUR_RGB32; - if(p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) { - cinfo->out_color_space = JCS_EXT_BGRX; - new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; - } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) { - cinfo->out_color_space = JCS_EXT_XRGB; - new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; - } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) { - cinfo->out_color_space = JCS_EXT_XBGR; - new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; - } else { - /* Assume RGBA */ - cinfo->out_color_space = JCS_EXT_RGBX; - new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; - } - break; + new_colours = ZM_COLOUR_RGB32; + if(p_subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + cinfo->out_color_space = JCS_EXT_BGRX; + new_subpixelorder = ZM_SUBPIX_ORDER_BGRA; + } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + cinfo->out_color_space = JCS_EXT_XRGB; + new_subpixelorder = ZM_SUBPIX_ORDER_ARGB; + } else if(p_subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + cinfo->out_color_space = JCS_EXT_XBGR; + new_subpixelorder = ZM_SUBPIX_ORDER_ABGR; + } else { + /* Assume RGBA */ + cinfo->out_color_space = JCS_EXT_RGBX; + new_subpixelorder = ZM_SUBPIX_ORDER_RGBA; + } + break; #else - Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead."); + Warning("libjpeg-turbo is required for reading a JPEG directly into a RGB32 buffer, reading into a RGB24 buffer instead."); #endif - } - case ZM_COLOUR_RGB24: - default: - { - new_colours = ZM_COLOUR_RGB24; - if(p_subpixelorder == ZM_SUBPIX_ORDER_BGR) { -#ifdef JCS_EXTENSIONS - cinfo->out_color_space = JCS_EXT_BGR; - new_subpixelorder = ZM_SUBPIX_ORDER_BGR; + } + case ZM_COLOUR_RGB24: + default: + { + new_colours = ZM_COLOUR_RGB24; + if(p_subpixelorder == ZM_SUBPIX_ORDER_BGR) { +#ifdef JCS_EXTENSIONS + cinfo->out_color_space = JCS_EXT_BGR; + new_subpixelorder = ZM_SUBPIX_ORDER_BGR; #else - Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); - cinfo->out_color_space = JCS_RGB; - new_subpixelorder = ZM_SUBPIX_ORDER_RGB; + Warning("libjpeg-turbo is required for reading a JPEG directly into a BGR24 buffer, reading into a RGB24 buffer instead."); + cinfo->out_color_space = JCS_RGB; + new_subpixelorder = ZM_SUBPIX_ORDER_RGB; #endif - } else { - /* Assume RGB */ + } else { + /* Assume RGB */ /* #ifdef JCS_EXTENSIONS - cinfo->out_color_space = JCS_EXT_RGB; + cinfo->out_color_space = JCS_EXT_RGB; #else - cinfo->out_color_space = JCS_RGB; + cinfo->out_color_space = JCS_RGB; #endif */ - cinfo->out_color_space = JCS_RGB; - new_subpixelorder = ZM_SUBPIX_ORDER_RGB; - } - break; - } - } - - if(WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL) { - Error("Failed requesting writeable buffer for reading JPEG image."); - jpeg_abort_decompress( cinfo ); - return( false ); - } + cinfo->out_color_space = JCS_RGB; + new_subpixelorder = ZM_SUBPIX_ORDER_RGB; + } + break; + } + } + + if(WriteBuffer(new_width, new_height, new_colours, new_subpixelorder) == NULL) { + Error("Failed requesting writeable buffer for reading JPEG image."); + jpeg_abort_decompress( cinfo ); + return( false ); + } - jpeg_start_decompress( cinfo ); + jpeg_start_decompress( cinfo ); - JSAMPROW row_pointer; /* pointer to a single row */ - int row_stride = width * colours; /* physical row width in buffer */ - while ( cinfo->output_scanline < cinfo->output_height ) - { - row_pointer = &buffer[cinfo->output_scanline * row_stride]; - jpeg_read_scanlines( cinfo, &row_pointer, 1 ); - } + JSAMPROW row_pointer; /* pointer to a single row */ + int row_stride = width * colours; /* physical row width in buffer */ + while ( cinfo->output_scanline < cinfo->output_height ) + { + row_pointer = &buffer[cinfo->output_scanline * row_stride]; + jpeg_read_scanlines( cinfo, &row_pointer, 1 ); + } - jpeg_finish_decompress( cinfo ); + jpeg_finish_decompress( cinfo ); - return( true ); + return( true ); } bool Image::EncodeJpeg( JOCTET *outbuffer, int *outbuffer_size, int quality_override ) const { - if ( config.colour_jpeg_files && colours == ZM_COLOUR_GRAY8 ) - { - Image temp_image( *this ); - temp_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB ); - return( temp_image.EncodeJpeg( outbuffer, outbuffer_size, quality_override ) ); - } + if ( config.colour_jpeg_files && colours == ZM_COLOUR_GRAY8 ) + { + Image temp_image( *this ); + temp_image.Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB ); + return( temp_image.EncodeJpeg( outbuffer, outbuffer_size, quality_override ) ); + } - int quality = quality_override?quality_override:config.jpeg_stream_quality; + int quality = quality_override?quality_override:config.jpeg_stream_quality; - struct jpeg_compress_struct *cinfo = jpg_ccinfo[quality]; + struct jpeg_compress_struct *cinfo = jpg_ccinfo[quality]; - if ( !cinfo ) - { - cinfo = jpg_ccinfo[quality] = new jpeg_compress_struct; - cinfo->err = jpeg_std_error( &jpg_err.pub ); - jpg_err.pub.error_exit = zm_jpeg_error_exit; - jpg_err.pub.emit_message = zm_jpeg_emit_message; - jpeg_create_compress( cinfo ); - } + if ( !cinfo ) + { + cinfo = jpg_ccinfo[quality] = new jpeg_compress_struct; + cinfo->err = jpeg_std_error( &jpg_err.pub ); + jpg_err.pub.error_exit = zm_jpeg_error_exit; + jpg_err.pub.emit_message = zm_jpeg_emit_message; + jpeg_create_compress( cinfo ); + } - zm_jpeg_mem_dest( cinfo, outbuffer, outbuffer_size ); + zm_jpeg_mem_dest( cinfo, outbuffer, outbuffer_size ); - cinfo->image_width = width; /* image width and height, in pixels */ - cinfo->image_height = height; + cinfo->image_width = width; /* image width and height, in pixels */ + cinfo->image_height = height; - switch(colours) { - case ZM_COLOUR_GRAY8: - { - cinfo->input_components = 1; - cinfo->in_color_space = JCS_GRAYSCALE; - break; - } - case ZM_COLOUR_RGB32: - { + switch(colours) { + case ZM_COLOUR_GRAY8: + { + cinfo->input_components = 1; + cinfo->in_color_space = JCS_GRAYSCALE; + break; + } + case ZM_COLOUR_RGB32: + { #ifdef JCS_EXTENSIONS - cinfo->input_components = 4; - if(subpixelorder == ZM_SUBPIX_ORDER_BGRA) { - cinfo->in_color_space = JCS_EXT_BGRX; - } else if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) { - cinfo->in_color_space = JCS_EXT_XRGB; - } else if(subpixelorder == ZM_SUBPIX_ORDER_ABGR) { - cinfo->in_color_space = JCS_EXT_XBGR; - } else { - /* Assume RGBA */ - cinfo->in_color_space = JCS_EXT_RGBX; - } + cinfo->input_components = 4; + if(subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + cinfo->in_color_space = JCS_EXT_BGRX; + } else if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + cinfo->in_color_space = JCS_EXT_XRGB; + } else if(subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + cinfo->in_color_space = JCS_EXT_XBGR; + } else { + /* Assume RGBA */ + cinfo->in_color_space = JCS_EXT_RGBX; + } #else - Error("libjpeg-turbo is required for JPEG encoding directly from RGB32 source"); - jpeg_abort_compress( cinfo ); - return(false); + Error("libjpeg-turbo is required for JPEG encoding directly from RGB32 source"); + jpeg_abort_compress( cinfo ); + return(false); #endif - break; - } - case ZM_COLOUR_RGB24: - default: - { - cinfo->input_components = 3; - if(subpixelorder == ZM_SUBPIX_ORDER_BGR) { + break; + } + case ZM_COLOUR_RGB24: + default: + { + cinfo->input_components = 3; + if(subpixelorder == ZM_SUBPIX_ORDER_BGR) { #ifdef JCS_EXTENSIONS - cinfo->in_color_space = JCS_EXT_BGR; + cinfo->in_color_space = JCS_EXT_BGR; #else - Error("libjpeg-turbo is required for JPEG encoding directly from BGR24 source"); - jpeg_abort_compress( cinfo ); - return(false); + Error("libjpeg-turbo is required for JPEG encoding directly from BGR24 source"); + jpeg_abort_compress( cinfo ); + return(false); #endif - } else { - /* Assume RGB */ + } else { + /* Assume RGB */ /* #ifdef JCS_EXTENSIONS - cinfo->out_color_space = JCS_EXT_RGB; + cinfo->out_color_space = JCS_EXT_RGB; #else - cinfo->out_color_space = JCS_RGB; + cinfo->out_color_space = JCS_RGB; #endif */ - cinfo->in_color_space = JCS_RGB; - } - break; - } - } - - jpeg_set_defaults( cinfo ); - jpeg_set_quality( cinfo, quality, FALSE ); - cinfo->dct_method = JDCT_FASTEST; + cinfo->in_color_space = JCS_RGB; + } + break; + } + } + + jpeg_set_defaults( cinfo ); + jpeg_set_quality( cinfo, quality, FALSE ); + cinfo->dct_method = JDCT_FASTEST; - jpeg_start_compress( cinfo, TRUE ); + jpeg_start_compress( cinfo, TRUE ); - JSAMPROW row_pointer; /* pointer to a single row */ - int row_stride = cinfo->image_width * colours; /* physical row width in buffer */ - while ( cinfo->next_scanline < cinfo->image_height ) - { - row_pointer = &buffer[cinfo->next_scanline * row_stride]; - jpeg_write_scanlines( cinfo, &row_pointer, 1 ); - } + JSAMPROW row_pointer; /* pointer to a single row */ + int row_stride = cinfo->image_width * colours; /* physical row width in buffer */ + while ( cinfo->next_scanline < cinfo->image_height ) + { + row_pointer = &buffer[cinfo->next_scanline * row_stride]; + jpeg_write_scanlines( cinfo, &row_pointer, 1 ); + } - jpeg_finish_compress( cinfo ); + jpeg_finish_compress( cinfo ); - return( true ); + return( true ); } #if HAVE_ZLIB_H bool Image::Unzip( const Bytef *inbuffer, unsigned long inbuffer_size ) { - unsigned long zip_size = size; - int result = uncompress( buffer, &zip_size, inbuffer, inbuffer_size ); - if ( result != Z_OK ) - { - Error( "Unzip failed, result = %d", result ); - return( false ); - } - if ( zip_size != (unsigned int)size ) - { - Error( "Unzip failed, size mismatch, expected %d bytes, got %ld", size, zip_size ); - return( false ); - } - return( true ); + unsigned long zip_size = size; + int result = uncompress( buffer, &zip_size, inbuffer, inbuffer_size ); + if ( result != Z_OK ) + { + Error( "Unzip failed, result = %d", result ); + return( false ); + } + if ( zip_size != (unsigned int)size ) + { + Error( "Unzip failed, size mismatch, expected %d bytes, got %ld", size, zip_size ); + return( false ); + } + return( true ); } bool Image::Zip( Bytef *outbuffer, unsigned long *outbuffer_size, int compression_level ) const { - int result = compress2( outbuffer, outbuffer_size, buffer, size, compression_level ); - if ( result != Z_OK ) - { - Error( "Zip failed, result = %d", result ); - return( false ); - } - return( true ); + int result = compress2( outbuffer, outbuffer_size, buffer, size, compression_level ); + if ( result != Z_OK ) + { + Error( "Zip failed, result = %d", result ); + return( false ); + } + return( true ); } #endif // HAVE_ZLIB_H bool Image::Crop( unsigned int lo_x, unsigned int lo_y, unsigned int hi_x, unsigned int hi_y ) { - unsigned int new_width = (hi_x-lo_x)+1; - unsigned int new_height = (hi_y-lo_y)+1; + unsigned int new_width = (hi_x-lo_x)+1; + unsigned int new_height = (hi_y-lo_y)+1; - if ( lo_x > hi_x || lo_y > hi_y ) - { - Error( "Invalid or reversed crop region %d,%d -> %d,%d", lo_x, lo_y, hi_x, hi_y ); - return( false ); - } - if ( lo_x < 0 || hi_x > (width-1) || ( lo_y < 0 || hi_y > (height-1) ) ) - { - Error( "Attempting to crop outside image, %d,%d -> %d,%d not in %d,%d", lo_x, lo_y, hi_x, hi_y, width-1, height-1 ); - return( false ); - } + if ( lo_x > hi_x || lo_y > hi_y ) + { + Error( "Invalid or reversed crop region %d,%d -> %d,%d", lo_x, lo_y, hi_x, hi_y ); + return( false ); + } + if ( lo_x < 0 || hi_x > (width-1) || ( lo_y < 0 || hi_y > (height-1) ) ) + { + Error( "Attempting to crop outside image, %d,%d -> %d,%d not in %d,%d", lo_x, lo_y, hi_x, hi_y, width-1, height-1 ); + return( false ); + } - if ( new_width == width && new_height == height ) - { - return( true ); - } + if ( new_width == width && new_height == height ) + { + return( true ); + } - unsigned int new_size = new_width*new_height*colours; - uint8_t *new_buffer = AllocBuffer(new_size); - - unsigned int new_stride = new_width*colours; - for ( unsigned int y = lo_y, ny = 0; y <= hi_y; y++, ny++ ) - { - unsigned char *pbuf = &buffer[((y*width)+lo_x)*colours]; - unsigned char *pnbuf = &new_buffer[(ny*new_width)*colours]; - memcpy( pnbuf, pbuf, new_stride ); - } + unsigned int new_size = new_width*new_height*colours; + uint8_t *new_buffer = AllocBuffer(new_size); + + unsigned int new_stride = new_width*colours; + for ( unsigned int y = lo_y, ny = 0; y <= hi_y; y++, ny++ ) + { + unsigned char *pbuf = &buffer[((y*width)+lo_x)*colours]; + unsigned char *pnbuf = &new_buffer[(ny*new_width)*colours]; + memcpy( pnbuf, pbuf, new_stride ); + } - AssignDirect(new_width, new_height, colours, subpixelorder, new_buffer, new_size, ZM_BUFTYPE_ZM); + AssignDirect(new_width, new_height, colours, subpixelorder, new_buffer, new_size, ZM_BUFTYPE_ZM); - return( true ); + return( true ); } bool Image::Crop( const Box &limits ) { - return( Crop( limits.LoX(), limits.LoY(), limits.HiX(), limits.HiY() ) ); + return( Crop( limits.LoX(), limits.LoY(), limits.HiX(), limits.HiY() ) ); } /* Far from complete */ /* Need to implement all possible of overlays possible */ void Image::Overlay( const Image &image ) { - if ( !(width == image.width && height == image.height) ) - { - Panic( "Attempt to overlay different sized images, expected %dx%d, got %dx%d", width, height, image.width, image.height ); - } - - if( colours == image.colours && subpixelorder != image.subpixelorder ) { - Warning("Attempt to overlay images of same format but with different subpixel order."); - } - - /* Grayscale ontop of grayscale - complete */ - if ( colours == ZM_COLOUR_GRAY8 && image.colours == ZM_COLOUR_GRAY8 ) { - const uint8_t* const max_ptr = buffer+size; - const uint8_t* psrc = image.buffer; - uint8_t* pdest = buffer; - - while( pdest < max_ptr ) - { - if ( *psrc ) - { - *pdest = *psrc; - } - pdest++; - psrc++; - } - - /* RGB24 ontop of grayscale - convert to same format first - complete */ - } else if ( colours == ZM_COLOUR_GRAY8 && image.colours == ZM_COLOUR_RGB24 ) { - Colourise(image.colours, image.subpixelorder); - - const uint8_t* const max_ptr = buffer+size; - const uint8_t* psrc = image.buffer; - uint8_t* pdest = buffer; - - while( pdest < max_ptr ) - { - if ( RED_PTR_RGBA(psrc) || GREEN_PTR_RGBA(psrc) || BLUE_PTR_RGBA(psrc) ) - { - RED_PTR_RGBA(pdest) = RED_PTR_RGBA(psrc); - GREEN_PTR_RGBA(pdest) = GREEN_PTR_RGBA(psrc); - BLUE_PTR_RGBA(pdest) = BLUE_PTR_RGBA(psrc); - } - pdest += 3; - psrc += 3; - } - - /* RGB32 ontop of grayscale - convert to same format first - complete */ - } else if( colours == ZM_COLOUR_GRAY8 && image.colours == ZM_COLOUR_RGB32 ) { - Colourise(image.colours, image.subpixelorder); - - const Rgb* const max_ptr = (Rgb*)(buffer+size); - const Rgb* prsrc = (Rgb*)image.buffer; - Rgb* prdest = (Rgb*)buffer; - - if(subpixelorder == ZM_SUBPIX_ORDER_RGBA || subpixelorder == ZM_SUBPIX_ORDER_BGRA) { - /* RGB\BGR\RGBA\BGRA subpixel order - Alpha byte is last */ - while (prdest < max_ptr) { - if ( RED_PTR_RGBA(prsrc) || GREEN_PTR_RGBA(prsrc) || BLUE_PTR_RGBA(prsrc) ) - { - *prdest = *prsrc; - } - prdest++; - prsrc++; - } - } else { - /* ABGR\ARGB subpixel order - Alpha byte is first */ - while (prdest < max_ptr) { - if ( RED_PTR_ABGR(prsrc) || GREEN_PTR_ABGR(prsrc) || BLUE_PTR_ABGR(prsrc) ) - { - *prdest = *prsrc; - } - prdest++; - prsrc++; - } - } - - /* Grayscale ontop of RGB24 - complete */ - } else if ( colours == ZM_COLOUR_RGB24 && image.colours == ZM_COLOUR_GRAY8 ) { - const uint8_t* const max_ptr = buffer+size; - const uint8_t* psrc = image.buffer; - uint8_t* pdest = buffer; - - while( pdest < max_ptr ) - { - if ( *psrc ) - { - RED_PTR_RGBA(pdest) = GREEN_PTR_RGBA(pdest) = BLUE_PTR_RGBA(pdest) = *psrc; - } - pdest += 3; - psrc++; - } - - /* RGB24 ontop of RGB24 - not complete. need to take care of different subpixel orders */ - } else if ( colours == ZM_COLOUR_RGB24 && image.colours == ZM_COLOUR_RGB24 ) { - const uint8_t* const max_ptr = buffer+size; - const uint8_t* psrc = image.buffer; - uint8_t* pdest = buffer; - - while( pdest < max_ptr ) - { - if ( RED_PTR_RGBA(psrc) || GREEN_PTR_RGBA(psrc) || BLUE_PTR_RGBA(psrc) ) - { - RED_PTR_RGBA(pdest) = RED_PTR_RGBA(psrc); - GREEN_PTR_RGBA(pdest) = GREEN_PTR_RGBA(psrc); - BLUE_PTR_RGBA(pdest) = BLUE_PTR_RGBA(psrc); - } - pdest += 3; - psrc += 3; - } - - /* RGB32 ontop of RGB24 - TO BE DONE */ - } else if ( colours == ZM_COLOUR_RGB24 && image.colours == ZM_COLOUR_RGB32 ) { - Error("Overlay of RGB32 ontop of RGB24 is not supported."); - - /* Grayscale ontop of RGB32 - complete */ - } else if ( colours == ZM_COLOUR_RGB32 && image.colours == ZM_COLOUR_GRAY8 ) { - const Rgb* const max_ptr = (Rgb*)(buffer+size); - Rgb* prdest = (Rgb*)buffer; - const uint8_t* psrc = image.buffer; - - if(subpixelorder == ZM_SUBPIX_ORDER_RGBA || subpixelorder == ZM_SUBPIX_ORDER_BGRA) { - /* RGBA\BGRA subpixel order - Alpha byte is last */ - while (prdest < max_ptr) { - if ( *psrc ) - { - RED_PTR_RGBA(prdest) = GREEN_PTR_RGBA(prdest) = BLUE_PTR_RGBA(prdest) = *psrc; - } - prdest++; - psrc++; - } - } else { - /* ABGR\ARGB subpixel order - Alpha byte is first */ - while (prdest < max_ptr) { - if ( *psrc ) - { - RED_PTR_ABGR(prdest) = GREEN_PTR_ABGR(prdest) = BLUE_PTR_ABGR(prdest) = *psrc; - } - prdest++; - psrc++; - } - } - - /* RGB24 ontop of RGB32 - TO BE DONE */ - } else if ( colours == ZM_COLOUR_RGB32 && image.colours == ZM_COLOUR_RGB24 ) { - Error("Overlay of RGB24 ontop of RGB32 is not supported."); - - /* RGB32 ontop of RGB32 - not complete. need to take care of different subpixel orders */ - } else if ( colours == ZM_COLOUR_RGB32 && image.colours == ZM_COLOUR_RGB32 ) { - const Rgb* const max_ptr = (Rgb*)(buffer+size); - Rgb* prdest = (Rgb*)buffer; - const Rgb* prsrc = (Rgb*)image.buffer; - - if(image.subpixelorder == ZM_SUBPIX_ORDER_RGBA || image.subpixelorder == ZM_SUBPIX_ORDER_BGRA) { - /* RGB\BGR\RGBA\BGRA subpixel order - Alpha byte is last */ - while (prdest < max_ptr) { - if ( RED_PTR_RGBA(prsrc) || GREEN_PTR_RGBA(prsrc) || BLUE_PTR_RGBA(prsrc) ) - { - *prdest = *prsrc; - } - prdest++; - prsrc++; - } - } else { - /* ABGR\ARGB subpixel order - Alpha byte is first */ - while (prdest < max_ptr) { - if ( RED_PTR_ABGR(prsrc) || GREEN_PTR_ABGR(prsrc) || BLUE_PTR_ABGR(prsrc) ) - { - *prdest = *prsrc; - } - prdest++; - prsrc++; - } - } - } - + if ( !(width == image.width && height == image.height) ) + { + Panic( "Attempt to overlay different sized images, expected %dx%d, got %dx%d", width, height, image.width, image.height ); + } + + if( colours == image.colours && subpixelorder != image.subpixelorder ) { + Warning("Attempt to overlay images of same format but with different subpixel order."); + } + + /* Grayscale ontop of grayscale - complete */ + if ( colours == ZM_COLOUR_GRAY8 && image.colours == ZM_COLOUR_GRAY8 ) { + const uint8_t* const max_ptr = buffer+size; + const uint8_t* psrc = image.buffer; + uint8_t* pdest = buffer; + + while( pdest < max_ptr ) + { + if ( *psrc ) + { + *pdest = *psrc; + } + pdest++; + psrc++; + } + + /* RGB24 ontop of grayscale - convert to same format first - complete */ + } else if ( colours == ZM_COLOUR_GRAY8 && image.colours == ZM_COLOUR_RGB24 ) { + Colourise(image.colours, image.subpixelorder); + + const uint8_t* const max_ptr = buffer+size; + const uint8_t* psrc = image.buffer; + uint8_t* pdest = buffer; + + while( pdest < max_ptr ) + { + if ( RED_PTR_RGBA(psrc) || GREEN_PTR_RGBA(psrc) || BLUE_PTR_RGBA(psrc) ) + { + RED_PTR_RGBA(pdest) = RED_PTR_RGBA(psrc); + GREEN_PTR_RGBA(pdest) = GREEN_PTR_RGBA(psrc); + BLUE_PTR_RGBA(pdest) = BLUE_PTR_RGBA(psrc); + } + pdest += 3; + psrc += 3; + } + + /* RGB32 ontop of grayscale - convert to same format first - complete */ + } else if( colours == ZM_COLOUR_GRAY8 && image.colours == ZM_COLOUR_RGB32 ) { + Colourise(image.colours, image.subpixelorder); + + const Rgb* const max_ptr = (Rgb*)(buffer+size); + const Rgb* prsrc = (Rgb*)image.buffer; + Rgb* prdest = (Rgb*)buffer; + + if(subpixelorder == ZM_SUBPIX_ORDER_RGBA || subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + /* RGB\BGR\RGBA\BGRA subpixel order - Alpha byte is last */ + while (prdest < max_ptr) { + if ( RED_PTR_RGBA(prsrc) || GREEN_PTR_RGBA(prsrc) || BLUE_PTR_RGBA(prsrc) ) + { + *prdest = *prsrc; + } + prdest++; + prsrc++; + } + } else { + /* ABGR\ARGB subpixel order - Alpha byte is first */ + while (prdest < max_ptr) { + if ( RED_PTR_ABGR(prsrc) || GREEN_PTR_ABGR(prsrc) || BLUE_PTR_ABGR(prsrc) ) + { + *prdest = *prsrc; + } + prdest++; + prsrc++; + } + } + + /* Grayscale ontop of RGB24 - complete */ + } else if ( colours == ZM_COLOUR_RGB24 && image.colours == ZM_COLOUR_GRAY8 ) { + const uint8_t* const max_ptr = buffer+size; + const uint8_t* psrc = image.buffer; + uint8_t* pdest = buffer; + + while( pdest < max_ptr ) + { + if ( *psrc ) + { + RED_PTR_RGBA(pdest) = GREEN_PTR_RGBA(pdest) = BLUE_PTR_RGBA(pdest) = *psrc; + } + pdest += 3; + psrc++; + } + + /* RGB24 ontop of RGB24 - not complete. need to take care of different subpixel orders */ + } else if ( colours == ZM_COLOUR_RGB24 && image.colours == ZM_COLOUR_RGB24 ) { + const uint8_t* const max_ptr = buffer+size; + const uint8_t* psrc = image.buffer; + uint8_t* pdest = buffer; + + while( pdest < max_ptr ) + { + if ( RED_PTR_RGBA(psrc) || GREEN_PTR_RGBA(psrc) || BLUE_PTR_RGBA(psrc) ) + { + RED_PTR_RGBA(pdest) = RED_PTR_RGBA(psrc); + GREEN_PTR_RGBA(pdest) = GREEN_PTR_RGBA(psrc); + BLUE_PTR_RGBA(pdest) = BLUE_PTR_RGBA(psrc); + } + pdest += 3; + psrc += 3; + } + + /* RGB32 ontop of RGB24 - TO BE DONE */ + } else if ( colours == ZM_COLOUR_RGB24 && image.colours == ZM_COLOUR_RGB32 ) { + Error("Overlay of RGB32 ontop of RGB24 is not supported."); + + /* Grayscale ontop of RGB32 - complete */ + } else if ( colours == ZM_COLOUR_RGB32 && image.colours == ZM_COLOUR_GRAY8 ) { + const Rgb* const max_ptr = (Rgb*)(buffer+size); + Rgb* prdest = (Rgb*)buffer; + const uint8_t* psrc = image.buffer; + + if(subpixelorder == ZM_SUBPIX_ORDER_RGBA || subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + /* RGBA\BGRA subpixel order - Alpha byte is last */ + while (prdest < max_ptr) { + if ( *psrc ) + { + RED_PTR_RGBA(prdest) = GREEN_PTR_RGBA(prdest) = BLUE_PTR_RGBA(prdest) = *psrc; + } + prdest++; + psrc++; + } + } else { + /* ABGR\ARGB subpixel order - Alpha byte is first */ + while (prdest < max_ptr) { + if ( *psrc ) + { + RED_PTR_ABGR(prdest) = GREEN_PTR_ABGR(prdest) = BLUE_PTR_ABGR(prdest) = *psrc; + } + prdest++; + psrc++; + } + } + + /* RGB24 ontop of RGB32 - TO BE DONE */ + } else if ( colours == ZM_COLOUR_RGB32 && image.colours == ZM_COLOUR_RGB24 ) { + Error("Overlay of RGB24 ontop of RGB32 is not supported."); + + /* RGB32 ontop of RGB32 - not complete. need to take care of different subpixel orders */ + } else if ( colours == ZM_COLOUR_RGB32 && image.colours == ZM_COLOUR_RGB32 ) { + const Rgb* const max_ptr = (Rgb*)(buffer+size); + Rgb* prdest = (Rgb*)buffer; + const Rgb* prsrc = (Rgb*)image.buffer; + + if(image.subpixelorder == ZM_SUBPIX_ORDER_RGBA || image.subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + /* RGB\BGR\RGBA\BGRA subpixel order - Alpha byte is last */ + while (prdest < max_ptr) { + if ( RED_PTR_RGBA(prsrc) || GREEN_PTR_RGBA(prsrc) || BLUE_PTR_RGBA(prsrc) ) + { + *prdest = *prsrc; + } + prdest++; + prsrc++; + } + } else { + /* ABGR\ARGB subpixel order - Alpha byte is first */ + while (prdest < max_ptr) { + if ( RED_PTR_ABGR(prsrc) || GREEN_PTR_ABGR(prsrc) || BLUE_PTR_ABGR(prsrc) ) + { + *prdest = *prsrc; + } + prdest++; + prsrc++; + } + } + } + } /* RGB32 compatible: complete */ void Image::Overlay( const Image &image, unsigned int x, unsigned int y ) { - if ( !(width < image.width || height < image.height) ) - { - Panic( "Attempt to overlay image too big for destination, %dx%d > %dx%d", image.width, image.height, width, height ); - } + if ( !(width < image.width || height < image.height) ) + { + Panic( "Attempt to overlay image too big for destination, %dx%d > %dx%d", image.width, image.height, width, height ); + } - if ( !(width < (x+image.width) || height < (y+image.height)) ) - { - Panic( "Attempt to overlay image outside of destination bounds, %dx%d @ %dx%d > %dx%d", image.width, image.height, x, y, width, height ); - } + if ( !(width < (x+image.width) || height < (y+image.height)) ) + { + Panic( "Attempt to overlay image outside of destination bounds, %dx%d @ %dx%d > %dx%d", image.width, image.height, x, y, width, height ); + } - if ( !(colours == image.colours) ) - { - Panic( "Attempt to partial overlay differently coloured images, expected %d, got %d", colours, image.colours ); - } + if ( !(colours == image.colours) ) + { + Panic( "Attempt to partial overlay differently coloured images, expected %d, got %d", colours, image.colours ); + } - unsigned int lo_x = x; - unsigned int lo_y = y; - unsigned int hi_x = (x+image.width)-1; - unsigned int hi_y = (y+image.height-1); - if ( colours == ZM_COLOUR_GRAY8 ) - { - const uint8_t *psrc = image.buffer; - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - uint8_t *pdest = &buffer[(y*width)+lo_x]; - for ( unsigned int x = lo_x; x <= hi_x; x++ ) - { - *pdest++ = *psrc++; - } - } - } - else if ( colours == ZM_COLOUR_RGB24 ) - { - const uint8_t *psrc = image.buffer; - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - uint8_t *pdest = &buffer[colours*((y*width)+lo_x)]; - for ( unsigned int x = lo_x; x <= hi_x; x++ ) - { - *pdest++ = *psrc++; - *pdest++ = *psrc++; - *pdest++ = *psrc++; - } - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - const Rgb *psrc = (Rgb*)(image.buffer); - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - Rgb *pdest = (Rgb*)&buffer[((y*width)+lo_x)<<2]; - for ( unsigned int x = lo_x; x <= hi_x; x++ ) - { - *pdest++ = *psrc++; - } - } - } else { - Error("Overlay called with unexpected colours: %d", colours); - } - + unsigned int lo_x = x; + unsigned int lo_y = y; + unsigned int hi_x = (x+image.width)-1; + unsigned int hi_y = (y+image.height-1); + if ( colours == ZM_COLOUR_GRAY8 ) + { + const uint8_t *psrc = image.buffer; + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + uint8_t *pdest = &buffer[(y*width)+lo_x]; + for ( unsigned int x = lo_x; x <= hi_x; x++ ) + { + *pdest++ = *psrc++; + } + } + } + else if ( colours == ZM_COLOUR_RGB24 ) + { + const uint8_t *psrc = image.buffer; + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + uint8_t *pdest = &buffer[colours*((y*width)+lo_x)]; + for ( unsigned int x = lo_x; x <= hi_x; x++ ) + { + *pdest++ = *psrc++; + *pdest++ = *psrc++; + *pdest++ = *psrc++; + } + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + const Rgb *psrc = (Rgb*)(image.buffer); + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + Rgb *pdest = (Rgb*)&buffer[((y*width)+lo_x)<<2]; + for ( unsigned int x = lo_x; x <= hi_x; x++ ) + { + *pdest++ = *psrc++; + } + } + } else { + Error("Overlay called with unexpected colours: %d", colours); + } + } void Image::Blend( const Image &image, int transparency ) { #ifdef ZM_IMAGE_PROFILING - struct timespec start,end,diff; - unsigned long long executetime; - unsigned long milpixels; + struct timespec start,end,diff; + unsigned long long executetime; + unsigned long milpixels; #endif - uint8_t* new_buffer; - - if ( !(width == image.width && height == image.height && colours == image.colours && subpixelorder == image.subpixelorder) ) - { - Panic( "Attempt to blend different sized images, expected %dx%dx%d %d, got %dx%dx%d %d", width, height, colours, subpixelorder, image.width, image.height, image.colours, image.subpixelorder ); - } - - if(transparency <= 0) - return; - - new_buffer = AllocBuffer(size); - + uint8_t* new_buffer; + + if ( !(width == image.width && height == image.height && colours == image.colours && subpixelorder == image.subpixelorder) ) + { + Panic( "Attempt to blend different sized images, expected %dx%dx%d %d, got %dx%dx%d %d", width, height, colours, subpixelorder, image.width, image.height, image.colours, image.subpixelorder ); + } + + if(transparency <= 0) + return; + + new_buffer = AllocBuffer(size); + #ifdef ZM_IMAGE_PROFILING - clock_gettime(CLOCK_THREAD_CPUTIME_ID,&start); + clock_gettime(CLOCK_THREAD_CPUTIME_ID,&start); #endif - - /* Do the blending */ - (*fptr_blend)(buffer, image.buffer, new_buffer, size, transparency); - + + /* Do the blending */ + (*fptr_blend)(buffer, image.buffer, new_buffer, size, transparency); + #ifdef ZM_IMAGE_PROFILING - clock_gettime(CLOCK_THREAD_CPUTIME_ID,&end); - timespec_diff(&start,&end,&diff); - - executetime = (1000000000ull * diff.tv_sec) + diff.tv_nsec; - milpixels = (unsigned long)((long double)size)/((((long double)executetime)/1000)); - Debug(5, "Blend: %u colours blended in %llu nanoseconds, %lu million colours/s\n",size,executetime,milpixels); + clock_gettime(CLOCK_THREAD_CPUTIME_ID,&end); + timespec_diff(&start,&end,&diff); + + executetime = (1000000000ull * diff.tv_sec) + diff.tv_nsec; + milpixels = (unsigned long)((long double)size)/((((long double)executetime)/1000)); + Debug(5, "Blend: %u colours blended in %llu nanoseconds, %lu million colours/s\n",size,executetime,milpixels); #endif - - AssignDirect( width, height, colours, subpixelorder, new_buffer, size, ZM_BUFTYPE_ZM); + + AssignDirect( width, height, colours, subpixelorder, new_buffer, size, ZM_BUFTYPE_ZM); } Image *Image::Merge( unsigned int n_images, Image *images[] ) { - if ( n_images <= 0 ) return( 0 ); - if ( n_images == 1 ) return( new Image( *images[0] ) ); + if ( n_images <= 0 ) return( 0 ); + if ( n_images == 1 ) return( new Image( *images[0] ) ); - unsigned int width = images[0]->width; - unsigned int height = images[0]->height; - unsigned int colours = images[0]->colours; - for ( unsigned int i = 1; i < n_images; i++ ) - { - if ( !(width == images[i]->width && height == images[i]->height && colours == images[i]->colours) ) - { - Panic( "Attempt to merge different sized images, expected %dx%dx%d, got %dx%dx%d, for image %d", width, height, colours, images[i]->width, images[i]->height, images[i]->colours, i ); - } - } + unsigned int width = images[0]->width; + unsigned int height = images[0]->height; + unsigned int colours = images[0]->colours; + for ( unsigned int i = 1; i < n_images; i++ ) + { + if ( !(width == images[i]->width && height == images[i]->height && colours == images[i]->colours) ) + { + Panic( "Attempt to merge different sized images, expected %dx%dx%d, got %dx%dx%d, for image %d", width, height, colours, images[i]->width, images[i]->height, images[i]->colours, i ); + } + } - Image *result = new Image( width, height, images[0]->colours, images[0]->subpixelorder); - unsigned int size = result->size; - for ( unsigned int i = 0; i < size; i++ ) - { - unsigned int total = 0; - uint8_t *pdest = result->buffer; - for ( unsigned int j = 0; j < n_images; j++ ) - { - uint8_t *psrc = images[j]->buffer; - total += *psrc; - psrc++; - } - *pdest = total/n_images; - pdest++; - } - return( result ); + Image *result = new Image( width, height, images[0]->colours, images[0]->subpixelorder); + unsigned int size = result->size; + for ( unsigned int i = 0; i < size; i++ ) + { + unsigned int total = 0; + uint8_t *pdest = result->buffer; + for ( unsigned int j = 0; j < n_images; j++ ) + { + uint8_t *psrc = images[j]->buffer; + total += *psrc; + psrc++; + } + *pdest = total/n_images; + pdest++; + } + return( result ); } Image *Image::Merge( unsigned int n_images, Image *images[], double weight ) { - if ( n_images <= 0 ) return( 0 ); - if ( n_images == 1 ) return( new Image( *images[0] ) ); + if ( n_images <= 0 ) return( 0 ); + if ( n_images == 1 ) return( new Image( *images[0] ) ); - unsigned int width = images[0]->width; - unsigned int height = images[0]->height; - unsigned int colours = images[0]->colours; - for ( unsigned int i = 1; i < n_images; i++ ) - { - if ( !(width == images[i]->width && height == images[i]->height && colours == images[i]->colours) ) - { - Panic( "Attempt to merge different sized images, expected %dx%dx%d, got %dx%dx%d, for image %d", width, height, colours, images[i]->width, images[i]->height, images[i]->colours, i ); - } - } + unsigned int width = images[0]->width; + unsigned int height = images[0]->height; + unsigned int colours = images[0]->colours; + for ( unsigned int i = 1; i < n_images; i++ ) + { + if ( !(width == images[i]->width && height == images[i]->height && colours == images[i]->colours) ) + { + Panic( "Attempt to merge different sized images, expected %dx%dx%d, got %dx%dx%d, for image %d", width, height, colours, images[i]->width, images[i]->height, images[i]->colours, i ); + } + } - Image *result = new Image( *images[0] ); - unsigned int size = result->size; - double factor = 1.0*weight; - for ( unsigned int i = 1; i < n_images; i++ ) - { - uint8_t *pdest = result->buffer; - uint8_t *psrc = images[i]->buffer; - for ( unsigned int j = 0; j < size; j++ ) - { - *pdest = (uint8_t)(((*pdest)*(1.0-factor))+((*psrc)*factor)); - pdest++; - psrc++; - } - factor *= weight; - } - return( result ); + Image *result = new Image( *images[0] ); + unsigned int size = result->size; + double factor = 1.0*weight; + for ( unsigned int i = 1; i < n_images; i++ ) + { + uint8_t *pdest = result->buffer; + uint8_t *psrc = images[i]->buffer; + for ( unsigned int j = 0; j < size; j++ ) + { + *pdest = (uint8_t)(((*pdest)*(1.0-factor))+((*psrc)*factor)); + pdest++; + psrc++; + } + factor *= weight; + } + return( result ); } Image *Image::Highlight( unsigned int n_images, Image *images[], const Rgb threshold, const Rgb ref_colour ) { - if ( n_images <= 0 ) return( 0 ); - if ( n_images == 1 ) return( new Image( *images[0] ) ); + if ( n_images <= 0 ) return( 0 ); + if ( n_images == 1 ) return( new Image( *images[0] ) ); - unsigned int width = images[0]->width; - unsigned int height = images[0]->height; - unsigned int colours = images[0]->colours; - for ( unsigned int i = 1; i < n_images; i++ ) - { - if ( !(width == images[i]->width && height == images[i]->height && colours == images[i]->colours) ) - { - Panic( "Attempt to highlight different sized images, expected %dx%dx%d, got %dx%dx%d, for image %d", width, height, colours, images[i]->width, images[i]->height, images[i]->colours, i ); - } - } + unsigned int width = images[0]->width; + unsigned int height = images[0]->height; + unsigned int colours = images[0]->colours; + for ( unsigned int i = 1; i < n_images; i++ ) + { + if ( !(width == images[i]->width && height == images[i]->height && colours == images[i]->colours) ) + { + Panic( "Attempt to highlight different sized images, expected %dx%dx%d, got %dx%dx%d, for image %d", width, height, colours, images[i]->width, images[i]->height, images[i]->colours, i ); + } + } - Image *result = new Image( width, height, images[0]->colours, images[0]->subpixelorder ); - unsigned int size = result->size; - for ( unsigned int c = 0; c < colours; c++ ) - { - for ( unsigned int i = 0; i < size; i++ ) - { - unsigned int count = 0; - uint8_t *pdest = result->buffer+c; - for ( unsigned int j = 0; j < n_images; j++ ) - { - uint8_t *psrc = images[j]->buffer+c; + Image *result = new Image( width, height, images[0]->colours, images[0]->subpixelorder ); + unsigned int size = result->size; + for ( unsigned int c = 0; c < colours; c++ ) + { + for ( unsigned int i = 0; i < size; i++ ) + { + unsigned int count = 0; + uint8_t *pdest = result->buffer+c; + for ( unsigned int j = 0; j < n_images; j++ ) + { + uint8_t *psrc = images[j]->buffer+c; #ifndef SOLARIS - if ( (unsigned)abs((*psrc)-RGB_VAL(ref_colour,c)) >= RGB_VAL(threshold,c) ) + if ( (unsigned)abs((*psrc)-RGB_VAL(ref_colour,c)) >= RGB_VAL(threshold,c) ) #else - if ( (unsigned)std::abs((*psrc)-RGB_VAL(ref_colour,c)) >= RGB_VAL(threshold,c) ) + if ( (unsigned)std::abs((*psrc)-RGB_VAL(ref_colour,c)) >= RGB_VAL(threshold,c) ) #endif - { - count++; - } - psrc += colours; - } - *pdest = (count*255)/n_images; - pdest += 3; - } - } - return( result ); + { + count++; + } + psrc += colours; + } + *pdest = (count*255)/n_images; + pdest += 3; + } + } + return( result ); } /* New function to allow buffer re-using instead of allocationg 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; - unsigned long long executetime; - unsigned long milpixels; + struct timespec start,end,diff; + unsigned long long executetime; + unsigned long milpixels; #endif - - if ( !(width == image.width && height == image.height && colours == image.colours && subpixelorder == image.subpixelorder) ) - { - Panic( "Attempt to get delta of different sized images, expected %dx%dx%d %d, got %dx%dx%d %d", width, height, colours, subpixelorder, image.width, image.height, image.colours, image.subpixelorder); - } - - uint8_t *pdiff = targetimage->WriteBuffer(width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE); - - if(pdiff == NULL) { - Panic("Failed requesting writeable buffer for storing the delta image"); - } - + + if ( !(width == image.width && height == image.height && colours == image.colours && subpixelorder == image.subpixelorder) ) + { + Panic( "Attempt to get delta of different sized images, expected %dx%dx%d %d, got %dx%dx%d %d", width, height, colours, subpixelorder, image.width, image.height, image.colours, image.subpixelorder); + } + + uint8_t *pdiff = targetimage->WriteBuffer(width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE); + + if(pdiff == NULL) { + Panic("Failed requesting writeable buffer for storing the delta image"); + } + #ifdef ZM_IMAGE_PROFILING - clock_gettime(CLOCK_THREAD_CPUTIME_ID,&start); + clock_gettime(CLOCK_THREAD_CPUTIME_ID,&start); #endif - - switch(colours) { - case ZM_COLOUR_RGB24: - { - if(subpixelorder == ZM_SUBPIX_ORDER_BGR) { - /* BGR subpixel order */ - (*fptr_delta8_bgr)(buffer, image.buffer, pdiff, pixels); - } else { - /* Assume RGB subpixel order */ - (*fptr_delta8_rgb)(buffer, image.buffer, pdiff, pixels); - } - break; - } - case ZM_COLOUR_RGB32: - { - if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) { - /* ARGB subpixel order */ - (*fptr_delta8_argb)(buffer, image.buffer, pdiff, pixels); - } else if(subpixelorder == ZM_SUBPIX_ORDER_ABGR) { - /* ABGR subpixel order */ - (*fptr_delta8_abgr)(buffer, image.buffer, pdiff, pixels); - } else if(subpixelorder == ZM_SUBPIX_ORDER_BGRA) { - /* BGRA subpixel order */ - (*fptr_delta8_bgra)(buffer, image.buffer, pdiff, pixels); - } else { - /* Assume RGBA subpixel order */ - (*fptr_delta8_rgba)(buffer, image.buffer, pdiff, pixels); - } - break; - } - case ZM_COLOUR_GRAY8: - (*fptr_delta8_gray8)(buffer, image.buffer, pdiff, pixels); - break; - default: - Panic("Delta called with unexpected colours: %d",colours); - break; - } - + + switch(colours) { + case ZM_COLOUR_RGB24: + { + if(subpixelorder == ZM_SUBPIX_ORDER_BGR) { + /* BGR subpixel order */ + (*fptr_delta8_bgr)(buffer, image.buffer, pdiff, pixels); + } else { + /* Assume RGB subpixel order */ + (*fptr_delta8_rgb)(buffer, image.buffer, pdiff, pixels); + } + break; + } + case ZM_COLOUR_RGB32: + { + if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + /* ARGB subpixel order */ + (*fptr_delta8_argb)(buffer, image.buffer, pdiff, pixels); + } else if(subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + /* ABGR subpixel order */ + (*fptr_delta8_abgr)(buffer, image.buffer, pdiff, pixels); + } else if(subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + /* BGRA subpixel order */ + (*fptr_delta8_bgra)(buffer, image.buffer, pdiff, pixels); + } else { + /* Assume RGBA subpixel order */ + (*fptr_delta8_rgba)(buffer, image.buffer, pdiff, pixels); + } + break; + } + case ZM_COLOUR_GRAY8: + (*fptr_delta8_gray8)(buffer, image.buffer, pdiff, pixels); + break; + default: + Panic("Delta called with unexpected colours: %d",colours); + break; + } + #ifdef ZM_IMAGE_PROFILING - clock_gettime(CLOCK_THREAD_CPUTIME_ID,&end); - timespec_diff(&start,&end,&diff); - - executetime = (1000000000ull * diff.tv_sec) + diff.tv_nsec; - milpixels = (unsigned long)((long double)pixels)/((((long double)executetime)/1000)); - Debug(5, "Delta: %u delta pixels generated in %llu nanoseconds, %lu million pixels/s\n",pixels,executetime,milpixels); + clock_gettime(CLOCK_THREAD_CPUTIME_ID,&end); + timespec_diff(&start,&end,&diff); + + executetime = (1000000000ull * diff.tv_sec) + diff.tv_nsec; + milpixels = (unsigned long)((long double)pixels)/((((long double)executetime)/1000)); + Debug(5, "Delta: %u delta pixels generated in %llu nanoseconds, %lu million pixels/s\n",pixels,executetime,milpixels); #endif } const Coord Image::centreCoord( const char *text ) const { - int index = 0; - int line_no = 0; - int text_len = strlen( text ); - int line_len = 0; - int max_line_len = 0; - const char *line = text; + int index = 0; + int line_no = 0; + int text_len = strlen( text ); + int line_len = 0; + int max_line_len = 0; + const char *line = text; - while ( (index < text_len) && (line_len = strcspn( line, "\n" )) ) + while ( (index < text_len) && (line_len = strcspn( line, "\n" )) ) + { + if ( line_len > max_line_len ) + max_line_len = line_len; + + index += line_len; + while ( text[index] == '\n' ) { - if ( line_len > max_line_len ) - max_line_len = line_len; - - index += line_len; - while ( text[index] == '\n' ) - { - index++; - } - line = text+index; - line_no++; + index++; } - int x = (width - (max_line_len * CHAR_WIDTH) ) / 2; - int y = (height - (line_no * LINE_HEIGHT) ) / 2; - return( Coord( x, y ) ); + line = text+index; + line_no++; + } + int x = (width - (max_line_len * CHAR_WIDTH) ) / 2; + int y = (height - (line_no * LINE_HEIGHT) ) / 2; + return( Coord( x, y ) ); } /* RGB32 compatible: complete */ void Image::MaskPrivacy( const unsigned char *p_bitmask, const Rgb pixel_colour ) { - const uint8_t pixel_r_col = RED_VAL_RGBA(pixel_colour); - const uint8_t pixel_g_col = GREEN_VAL_RGBA(pixel_colour); - const uint8_t pixel_b_col = BLUE_VAL_RGBA(pixel_colour); - const uint8_t pixel_bw_col = pixel_colour & 0xff; - const Rgb pixel_rgb_col = rgb_convert(pixel_colour,subpixelorder); + const uint8_t pixel_r_col = RED_VAL_RGBA(pixel_colour); + const uint8_t pixel_g_col = GREEN_VAL_RGBA(pixel_colour); + const uint8_t pixel_b_col = BLUE_VAL_RGBA(pixel_colour); + const uint8_t pixel_bw_col = pixel_colour & 0xff; + const Rgb pixel_rgb_col = rgb_convert(pixel_colour,subpixelorder); - unsigned char *ptr = &buffer[0]; - unsigned int i = 0; + unsigned char *ptr = &buffer[0]; + unsigned int i = 0; - for ( unsigned int y = 0; y < height; y++ ) + for ( unsigned int y = 0; y < height; y++ ) + { + if ( colours == ZM_COLOUR_GRAY8 ) { - if ( colours == ZM_COLOUR_GRAY8 ) - { - for ( unsigned int x = 0; x < width; x++, ptr++ ) - { - if ( p_bitmask[i] ) - *ptr = pixel_bw_col; - i++; - } - } - else if ( colours == ZM_COLOUR_RGB24 ) - { - for ( unsigned int x = 0; x < width; x++, ptr += colours ) - { - if ( p_bitmask[i] ) - { - RED_PTR_RGBA(ptr) = pixel_r_col; - GREEN_PTR_RGBA(ptr) = pixel_g_col; - BLUE_PTR_RGBA(ptr) = pixel_b_col; - } - i++; - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - for ( unsigned int x = 0; x < width; x++, ptr += colours ) - { - Rgb *temp_ptr = (Rgb*)ptr; - if ( p_bitmask[i] ) - *temp_ptr = pixel_rgb_col; - i++; - } - } else { - Panic("MaskPrivacy called with unexpected colours: %d", colours); - return; - } - + for ( unsigned int x = 0; x < width; x++, ptr++ ) + { + if ( p_bitmask[i] ) + *ptr = pixel_bw_col; + i++; + } } + else if ( colours == ZM_COLOUR_RGB24 ) + { + for ( unsigned int x = 0; x < width; x++, ptr += colours ) + { + if ( p_bitmask[i] ) + { + RED_PTR_RGBA(ptr) = pixel_r_col; + GREEN_PTR_RGBA(ptr) = pixel_g_col; + BLUE_PTR_RGBA(ptr) = pixel_b_col; + } + i++; + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + for ( unsigned int x = 0; x < width; x++, ptr += colours ) + { + Rgb *temp_ptr = (Rgb*)ptr; + if ( p_bitmask[i] ) + *temp_ptr = pixel_rgb_col; + i++; + } + } else { + Panic("MaskPrivacy called with unexpected colours: %d", colours); + return; + } + + } } /* RGB32 compatible: complete */ void Image::Annotate( const char *p_text, const Coord &coord, const unsigned int size, const Rgb fg_colour, const Rgb bg_colour ) { - strncpy( text, p_text, sizeof(text) ); + strncpy( text, p_text, sizeof(text) ); - unsigned int index = 0; - unsigned int line_no = 0; - unsigned int text_len = strlen( text ); - unsigned int line_len = 0; - const char *line = text; + unsigned int index = 0; + unsigned int line_no = 0; + unsigned int text_len = strlen( text ); + unsigned int line_len = 0; + const char *line = text; - const uint8_t fg_r_col = RED_VAL_RGBA(fg_colour); - const uint8_t fg_g_col = GREEN_VAL_RGBA(fg_colour); - const uint8_t fg_b_col = BLUE_VAL_RGBA(fg_colour); - const uint8_t fg_bw_col = fg_colour & 0xff; - const Rgb fg_rgb_col = rgb_convert(fg_colour,subpixelorder); - const bool fg_trans = (fg_colour == RGB_TRANSPARENT); - - const uint8_t bg_r_col = RED_VAL_RGBA(bg_colour); - const uint8_t bg_g_col = GREEN_VAL_RGBA(bg_colour); - const uint8_t bg_b_col = BLUE_VAL_RGBA(bg_colour); - const uint8_t bg_bw_col = bg_colour & 0xff; - const Rgb bg_rgb_col = rgb_convert(bg_colour,subpixelorder); - const bool bg_trans = (bg_colour == RGB_TRANSPARENT); + const uint8_t fg_r_col = RED_VAL_RGBA(fg_colour); + const uint8_t fg_g_col = GREEN_VAL_RGBA(fg_colour); + const uint8_t fg_b_col = BLUE_VAL_RGBA(fg_colour); + const uint8_t fg_bw_col = fg_colour & 0xff; + const Rgb fg_rgb_col = rgb_convert(fg_colour,subpixelorder); + const bool fg_trans = (fg_colour == RGB_TRANSPARENT); + + const uint8_t bg_r_col = RED_VAL_RGBA(bg_colour); + const uint8_t bg_g_col = GREEN_VAL_RGBA(bg_colour); + const uint8_t bg_b_col = BLUE_VAL_RGBA(bg_colour); + const uint8_t bg_bw_col = bg_colour & 0xff; + const Rgb bg_rgb_col = rgb_convert(bg_colour,subpixelorder); + const bool bg_trans = (bg_colour == RGB_TRANSPARENT); - int zm_text_bitmask = 0x80; - if (size == 2) - zm_text_bitmask = 0x8000; + int zm_text_bitmask = 0x80; + if (size == 2) + zm_text_bitmask = 0x8000; - while ( (index < text_len) && (line_len = strcspn( line, "\n" )) ) + while ( (index < text_len) && (line_len = strcspn( line, "\n" )) ) + { + + unsigned int line_width = line_len * CHAR_WIDTH * size; + + unsigned int lo_line_x = coord.X(); + unsigned int lo_line_y = coord.Y() + (line_no * LINE_HEIGHT * size); + + unsigned int min_line_x = 0; + unsigned int max_line_x = width - line_width; + unsigned int min_line_y = 0; + unsigned int max_line_y = height - (LINE_HEIGHT * size); + + if ( lo_line_x > max_line_x ) + lo_line_x = max_line_x; + if ( lo_line_x < min_line_x ) + lo_line_x = min_line_x; + if ( lo_line_y > max_line_y ) + lo_line_y = max_line_y; + if ( lo_line_y < min_line_y ) + lo_line_y = min_line_y; + + unsigned int hi_line_x = lo_line_x + line_width; + unsigned int hi_line_y = lo_line_y + (LINE_HEIGHT * size); + + // Clip anything that runs off the right of the screen + if ( hi_line_x > width ) + hi_line_x = width; + if ( hi_line_y > height ) + hi_line_y = height; + + if ( colours == ZM_COLOUR_GRAY8 ) { - - unsigned int line_width = line_len * CHAR_WIDTH * size; - - unsigned int lo_line_x = coord.X(); - unsigned int lo_line_y = coord.Y() + (line_no * LINE_HEIGHT * size); - - unsigned int min_line_x = 0; - unsigned int max_line_x = width - line_width; - unsigned int min_line_y = 0; - unsigned int max_line_y = height - (LINE_HEIGHT * size); - - if ( lo_line_x > max_line_x ) - lo_line_x = max_line_x; - if ( lo_line_x < min_line_x ) - lo_line_x = min_line_x; - if ( lo_line_y > max_line_y ) - lo_line_y = max_line_y; - if ( lo_line_y < min_line_y ) - lo_line_y = min_line_y; - - unsigned int hi_line_x = lo_line_x + line_width; - unsigned int hi_line_y = lo_line_y + (LINE_HEIGHT * size); - - // Clip anything that runs off the right of the screen - if ( hi_line_x > width ) - hi_line_x = width; - if ( hi_line_y > height ) - hi_line_y = height; - - if ( colours == ZM_COLOUR_GRAY8 ) + unsigned char *ptr = &buffer[(lo_line_y*width)+lo_line_x]; + for ( unsigned int y = lo_line_y, r = 0; y < hi_line_y && r < (CHAR_HEIGHT * size); y++, r++, ptr += width ) + { + unsigned char *temp_ptr = ptr; + for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) { - unsigned char *ptr = &buffer[(lo_line_y*width)+lo_line_x]; - for ( unsigned int y = lo_line_y, r = 0; y < hi_line_y && r < (CHAR_HEIGHT * size); y++, r++, ptr += width ) + int f; + if (size == 2) + f = bigfontdata[(line[c] * CHAR_HEIGHT * size) + r]; + else + f = fontdata[(line[c] * CHAR_HEIGHT) + r]; + for ( unsigned int i = 0; i < (CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) + { + if ( f & (zm_text_bitmask >> i) ) { - unsigned char *temp_ptr = ptr; - for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) - { - int f; - if (size == 2) - f = bigfontdata[(line[c] * CHAR_HEIGHT * size) + r]; - else - f = fontdata[(line[c] * CHAR_HEIGHT) + r]; - for ( unsigned int i = 0; i < (CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) - { - if ( f & (zm_text_bitmask >> i) ) - { - if ( !fg_trans ) - *temp_ptr = fg_bw_col; - } - else if ( !bg_trans ) - { - *temp_ptr = bg_bw_col; - } - } - } + if ( !fg_trans ) + *temp_ptr = fg_bw_col; } - } - else if ( colours == ZM_COLOUR_RGB24 ) - { - unsigned int wc = width * colours; - - unsigned char *ptr = &buffer[((lo_line_y*width)+lo_line_x)*colours]; - for ( unsigned int y = lo_line_y, r = 0; y < hi_line_y && r < (CHAR_HEIGHT * size); y++, r++, ptr += wc ) + else if ( !bg_trans ) { - unsigned char *temp_ptr = ptr; - for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) - { - int f; - if (size == 2) - f = bigfontdata[(line[c] * CHAR_HEIGHT * size) + r]; - else - f = fontdata[(line[c] * CHAR_HEIGHT) + r]; - for ( unsigned int i = 0; i < (CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr += colours ) - { - if ( f & (zm_text_bitmask >> i) ) - { - if ( !fg_trans ) - { - RED_PTR_RGBA(temp_ptr) = fg_r_col; - GREEN_PTR_RGBA(temp_ptr) = fg_g_col; - BLUE_PTR_RGBA(temp_ptr) = fg_b_col; - } - } - else if ( !bg_trans ) - { - RED_PTR_RGBA(temp_ptr) = bg_r_col; - GREEN_PTR_RGBA(temp_ptr) = bg_g_col; - BLUE_PTR_RGBA(temp_ptr) = bg_b_col; - } - } - } + *temp_ptr = bg_bw_col; } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - unsigned int wc = width * colours; - - uint8_t *ptr = &buffer[((lo_line_y*width)+lo_line_x)<<2]; - for ( unsigned int y = lo_line_y, r = 0; y < hi_line_y && r < (CHAR_HEIGHT * size); y++, r++, ptr += wc ) - { - Rgb* temp_ptr = (Rgb*)ptr; - for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) - { - int f; - if (size == 2) - f = bigfontdata[(line[c] * CHAR_HEIGHT * size) + r]; - else - f = fontdata[(line[c] * CHAR_HEIGHT) + r]; - for ( unsigned int i = 0; i < (CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) - { - if ( f & (zm_text_bitmask >> i) ) - { - if ( !fg_trans ) - { - *temp_ptr = fg_rgb_col; - } - } - else if ( !bg_trans ) - { - *temp_ptr = bg_rgb_col; - } - } - } - } - - } else { - Panic("Annotate called with unexpected colours: %d",colours); - return; - } - - index += line_len; - while ( text[index] == '\n' ) - { - index++; + } } - line = text+index; - line_no++; + } } + else if ( colours == ZM_COLOUR_RGB24 ) + { + unsigned int wc = width * colours; + + unsigned char *ptr = &buffer[((lo_line_y*width)+lo_line_x)*colours]; + for ( unsigned int y = lo_line_y, r = 0; y < hi_line_y && r < (CHAR_HEIGHT * size); y++, r++, ptr += wc ) + { + unsigned char *temp_ptr = ptr; + for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) + { + int f; + if (size == 2) + f = bigfontdata[(line[c] * CHAR_HEIGHT * size) + r]; + else + f = fontdata[(line[c] * CHAR_HEIGHT) + r]; + for ( unsigned int i = 0; i < (CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr += colours ) + { + if ( f & (zm_text_bitmask >> i) ) + { + if ( !fg_trans ) + { + RED_PTR_RGBA(temp_ptr) = fg_r_col; + GREEN_PTR_RGBA(temp_ptr) = fg_g_col; + BLUE_PTR_RGBA(temp_ptr) = fg_b_col; + } + } + else if ( !bg_trans ) + { + RED_PTR_RGBA(temp_ptr) = bg_r_col; + GREEN_PTR_RGBA(temp_ptr) = bg_g_col; + BLUE_PTR_RGBA(temp_ptr) = bg_b_col; + } + } + } + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + unsigned int wc = width * colours; + + uint8_t *ptr = &buffer[((lo_line_y*width)+lo_line_x)<<2]; + for ( unsigned int y = lo_line_y, r = 0; y < hi_line_y && r < (CHAR_HEIGHT * size); y++, r++, ptr += wc ) + { + Rgb* temp_ptr = (Rgb*)ptr; + for ( unsigned int x = lo_line_x, c = 0; x < hi_line_x && c < line_len; c++ ) + { + int f; + if (size == 2) + f = bigfontdata[(line[c] * CHAR_HEIGHT * size) + r]; + else + f = fontdata[(line[c] * CHAR_HEIGHT) + r]; + for ( unsigned int i = 0; i < (CHAR_WIDTH * size) && x < hi_line_x; i++, x++, temp_ptr++ ) + { + if ( f & (zm_text_bitmask >> i) ) + { + if ( !fg_trans ) + { + *temp_ptr = fg_rgb_col; + } + } + else if ( !bg_trans ) + { + *temp_ptr = bg_rgb_col; + } + } + } + } + + } else { + Panic("Annotate called with unexpected colours: %d",colours); + return; + } + + index += line_len; + while ( text[index] == '\n' ) + { + index++; + } + line = text+index; + line_no++; + } } void Image::Timestamp( const char *label, const time_t when, const Coord &coord, const int size ) { - char time_text[64]; - strftime( time_text, sizeof(time_text), "%y/%m/%d %H:%M:%S", localtime( &when ) ); - char text[64]; - if ( label ) - { - snprintf( text, sizeof(text), "%s - %s", label, time_text ); - Annotate( text, coord, size ); - } - else - { - Annotate( time_text, coord, size ); - } + char time_text[64]; + strftime( time_text, sizeof(time_text), "%y/%m/%d %H:%M:%S", localtime( &when ) ); + char text[64]; + if ( label ) + { + snprintf( text, sizeof(text), "%s - %s", label, time_text ); + Annotate( text, coord, size ); + } + else + { + Annotate( time_text, coord, size ); + } } /* RGB32 compatible: complete */ void Image::Colourise(const unsigned int p_reqcolours, const unsigned int p_reqsubpixelorder) { - Debug(9, "Colourise: Req colours: %u Req subpixel order: %u Current colours: %u Current subpixel order: %u",p_reqcolours,p_reqsubpixelorder,colours,subpixelorder); - - if ( colours != ZM_COLOUR_GRAY8) { - Warning("Target image is already colourised, colours: %u",colours); - return; - } - - if ( p_reqcolours == ZM_COLOUR_RGB32 ) { - /* RGB32 */ - Rgb* new_buffer = (Rgb*)AllocBuffer(pixels*sizeof(Rgb)); - - const uint8_t *psrc = buffer; - Rgb* pdest = new_buffer; - Rgb subpixel; - Rgb newpixel; - - if ( p_reqsubpixelorder == ZM_SUBPIX_ORDER_ABGR || p_reqsubpixelorder == ZM_SUBPIX_ORDER_ARGB) { - /* ARGB\ABGR subpixel order. alpha byte is first (mem+0), so we need to shift the pixel left in the end */ - for(unsigned int i=0;iLo().X():0; - unsigned int lo_y = limits?limits->Lo().Y():0; - unsigned int hi_x = limits?limits->Hi().X():width-1; - unsigned int hi_y = limits?limits->Hi().Y():height-1; - if ( colours == ZM_COLOUR_GRAY8 ) - { - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - unsigned char *p = &buffer[(y*width)+lo_x]; - for ( unsigned int x = lo_x; x <= hi_x; x++, p++) - { - *p = colour; - } - } - } - else if ( colours == ZM_COLOUR_RGB24 ) - { - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - unsigned char *p = &buffer[colours*((y*width)+lo_x)]; - for ( unsigned int x = lo_x; x <= hi_x; x++, p += 3) - { - RED_PTR_RGBA(p) = RED_VAL_RGBA(colour); - GREEN_PTR_RGBA(p) = GREEN_VAL_RGBA(colour); - BLUE_PTR_RGBA(p) = BLUE_VAL_RGBA(colour); - } - } - } - else if ( colours == ZM_COLOUR_RGB32 ) /* RGB32 */ - { - for ( unsigned int y = lo_y; y <= (unsigned int)hi_y; y++ ) - { - Rgb *p = (Rgb*)&buffer[((y*width)+lo_x)<<2]; - - for ( unsigned int x = lo_x; x <= (unsigned int)hi_x; x++, p++) - { - /* Fast, copies the entire pixel in a single pass */ - *p = colour; - } - } - } + if ( !(colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB24 || colours == ZM_COLOUR_RGB32 ) ) + { + Panic( "Attempt to fill image with unexpected colours %d", colours ); + } + + /* Convert the colour's RGBA subpixel order into the image's subpixel order */ + colour = rgb_convert(colour,subpixelorder); + + unsigned int lo_x = limits?limits->Lo().X():0; + unsigned int lo_y = limits?limits->Lo().Y():0; + unsigned int hi_x = limits?limits->Hi().X():width-1; + unsigned int hi_y = limits?limits->Hi().Y():height-1; + if ( colours == ZM_COLOUR_GRAY8 ) + { + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + unsigned char *p = &buffer[(y*width)+lo_x]; + for ( unsigned int x = lo_x; x <= hi_x; x++, p++) + { + *p = colour; + } + } + } + else if ( colours == ZM_COLOUR_RGB24 ) + { + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + unsigned char *p = &buffer[colours*((y*width)+lo_x)]; + for ( unsigned int x = lo_x; x <= hi_x; x++, p += 3) + { + RED_PTR_RGBA(p) = RED_VAL_RGBA(colour); + GREEN_PTR_RGBA(p) = GREEN_VAL_RGBA(colour); + BLUE_PTR_RGBA(p) = BLUE_VAL_RGBA(colour); + } + } + } + else if ( colours == ZM_COLOUR_RGB32 ) /* RGB32 */ + { + for ( unsigned int y = lo_y; y <= (unsigned int)hi_y; y++ ) + { + Rgb *p = (Rgb*)&buffer[((y*width)+lo_x)<<2]; + + for ( unsigned int x = lo_x; x <= (unsigned int)hi_x; x++, p++) + { + /* Fast, copies the entire pixel in a single pass */ + *p = colour; + } + } + } } /* RGB32 compatible: complete */ void Image::Fill( Rgb colour, int density, const Box *limits ) { - /* Allow the faster version to be used if density is not used (density=1) */ - if(density <= 1) - return Fill(colour,limits); - - if ( !(colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB24 || colours == ZM_COLOUR_RGB32 ) ) - { - Panic( "Attempt to fill image with unexpected colours %d", colours ); - } - - /* Convert the colour's RGBA subpixel order into the image's subpixel order */ - colour = rgb_convert(colour,subpixelorder); + /* Allow the faster version to be used if density is not used (density=1) */ + if(density <= 1) + return Fill(colour,limits); + + if ( !(colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB24 || colours == ZM_COLOUR_RGB32 ) ) + { + Panic( "Attempt to fill image with unexpected colours %d", colours ); + } + + /* Convert the colour's RGBA subpixel order into the image's subpixel order */ + colour = rgb_convert(colour,subpixelorder); - unsigned int lo_x = limits?limits->Lo().X():0; - unsigned int lo_y = limits?limits->Lo().Y():0; - unsigned int hi_x = limits?limits->Hi().X():width-1; - unsigned int hi_y = limits?limits->Hi().Y():height-1; - if ( colours == ZM_COLOUR_GRAY8 ) - { - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - unsigned char *p = &buffer[(y*width)+lo_x]; - for ( unsigned int x = lo_x; x <= hi_x; x++, p++) - { - if ( ( x == lo_x || x == hi_x || y == lo_y || y == hi_y ) || (!(x%density) && !(y%density) ) ) - *p = colour; - } - } - } - else if ( colours == ZM_COLOUR_RGB24 ) - { - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - unsigned char *p = &buffer[colours*((y*width)+lo_x)]; - for ( unsigned int x = lo_x; x <= hi_x; x++, p += 3) - { - if ( ( x == lo_x || x == hi_x || y == lo_y || y == hi_y ) || (!(x%density) && !(y%density) ) ) { - RED_PTR_RGBA(p) = RED_VAL_RGBA(colour); - GREEN_PTR_RGBA(p) = GREEN_VAL_RGBA(colour); - BLUE_PTR_RGBA(p) = BLUE_VAL_RGBA(colour); - } - } - } - } - else if ( colours == ZM_COLOUR_RGB32 ) /* RGB32 */ - { - for ( unsigned int y = lo_y; y <= hi_y; y++ ) - { - Rgb* p = (Rgb*)&buffer[((y*width)+lo_x)<<2]; + unsigned int lo_x = limits?limits->Lo().X():0; + unsigned int lo_y = limits?limits->Lo().Y():0; + unsigned int hi_x = limits?limits->Hi().X():width-1; + unsigned int hi_y = limits?limits->Hi().Y():height-1; + if ( colours == ZM_COLOUR_GRAY8 ) + { + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + unsigned char *p = &buffer[(y*width)+lo_x]; + for ( unsigned int x = lo_x; x <= hi_x; x++, p++) + { + if ( ( x == lo_x || x == hi_x || y == lo_y || y == hi_y ) || (!(x%density) && !(y%density) ) ) + *p = colour; + } + } + } + else if ( colours == ZM_COLOUR_RGB24 ) + { + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + unsigned char *p = &buffer[colours*((y*width)+lo_x)]; + for ( unsigned int x = lo_x; x <= hi_x; x++, p += 3) + { + if ( ( x == lo_x || x == hi_x || y == lo_y || y == hi_y ) || (!(x%density) && !(y%density) ) ) { + RED_PTR_RGBA(p) = RED_VAL_RGBA(colour); + GREEN_PTR_RGBA(p) = GREEN_VAL_RGBA(colour); + BLUE_PTR_RGBA(p) = BLUE_VAL_RGBA(colour); + } + } + } + } + else if ( colours == ZM_COLOUR_RGB32 ) /* RGB32 */ + { + for ( unsigned int y = lo_y; y <= hi_y; y++ ) + { + Rgb* p = (Rgb*)&buffer[((y*width)+lo_x)<<2]; - for ( unsigned int x = lo_x; x <= hi_x; x++, p++) - { - if ( ( x == lo_x || x == hi_x || y == lo_y || y == hi_y ) || (!(x%density) && !(y%density) ) ) - /* Fast, copies the entire pixel in a single pass */ - *p = colour; - } - } - } - + for ( unsigned int x = lo_x; x <= hi_x; x++, p++) + { + if ( ( x == lo_x || x == hi_x || y == lo_y || y == hi_y ) || (!(x%density) && !(y%density) ) ) + /* Fast, copies the entire pixel in a single pass */ + *p = colour; + } + } + } + } /* RGB32 compatible: complete */ void Image::Outline( Rgb colour, const Polygon &polygon ) { - if ( !(colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB24 || colours == ZM_COLOUR_RGB32 ) ) - { - Panic( "Attempt to outline image with unexpected colours %d", colours ); - } - - /* Convert the colour's RGBA subpixel order into the image's subpixel order */ - colour = rgb_convert(colour,subpixelorder); - - int n_coords = polygon.getNumCoords(); - for ( int j = 0, i = n_coords-1; j < n_coords; i = j++ ) - { - const Coord &p1 = polygon.getCoord( i ); - const Coord &p2 = polygon.getCoord( j ); + if ( !(colours == ZM_COLOUR_GRAY8 || colours == ZM_COLOUR_RGB24 || colours == ZM_COLOUR_RGB32 ) ) + { + Panic( "Attempt to outline image with unexpected colours %d", colours ); + } + + /* Convert the colour's RGBA subpixel order into the image's subpixel order */ + colour = rgb_convert(colour,subpixelorder); + + int n_coords = polygon.getNumCoords(); + for ( int j = 0, i = n_coords-1; j < n_coords; i = j++ ) + { + const Coord &p1 = polygon.getCoord( i ); + const Coord &p2 = polygon.getCoord( j ); - int x1 = p1.X(); - int x2 = p2.X(); - int y1 = p1.Y(); - int y2 = p2.Y(); + int x1 = p1.X(); + int x2 = p2.X(); + int y1 = p1.Y(); + int y2 = p2.Y(); - double dx = x2 - x1; - double dy = y2 - y1; + double dx = x2 - x1; + double dy = y2 - y1; - double grad; + double grad; - //Debug( 9, "dx: %.2lf, dy: %.2lf", dx, dy ); - if ( fabs(dx) <= fabs(dy) ) - { - //Debug( 9, "dx <= dy" ); - if ( y1 != y2 ) - grad = dx/dy; - else - grad = width; + //Debug( 9, "dx: %.2lf, dy: %.2lf", dx, dy ); + if ( fabs(dx) <= fabs(dy) ) + { + //Debug( 9, "dx <= dy" ); + if ( y1 != y2 ) + grad = dx/dy; + else + grad = width; - double x; - int y, yinc = (y1 dy" ); - if ( x1 != x2 ) - grad = dy/dx; - else - grad = height; - //Debug( 9, "grad: %.2lf", grad ); + double x; + int y, yinc = (y1 dy" ); + if ( x1 != x2 ) + grad = dy/dx; + else + grad = height; + //Debug( 9, "grad: %.2lf", grad ); - double y; - int x, xinc = (x1= Logger::DEBUG9 ) - { - for ( int i = 0; i < n_global_edges; i++ ) - { - Debug( 9, "%d: min_y: %d, max_y:%d, min_x:%.2f, 1/m:%.2f", i, global_edges[i].min_y, global_edges[i].max_y, global_edges[i].min_x, global_edges[i]._1_m ); - } - } + if ( logLevel() >= Logger::DEBUG9 ) + { + for ( int i = 0; i < n_global_edges; i++ ) + { + Debug( 9, "%d: min_y: %d, max_y:%d, min_x:%.2f, 1/m:%.2f", i, global_edges[i].min_y, global_edges[i].max_y, global_edges[i].min_x, global_edges[i]._1_m ); + } + } #endif - int n_active_edges = 0; - Edge active_edges[n_global_edges]; - int y = global_edges[0].min_y; - do - { - for ( int i = 0; i < n_global_edges; i++ ) - { - if ( global_edges[i].min_y == y ) - { - Debug( 9, "Moving global edge" ); - active_edges[n_active_edges++] = global_edges[i]; - if ( i < (n_global_edges-1) ) - { - //memcpy( &global_edges[i], &global_edges[i+1], sizeof(*global_edges)*(n_global_edges-i) ); - memmove( &global_edges[i], &global_edges[i+1], sizeof(*global_edges)*(n_global_edges-i) ); - i--; - } - n_global_edges--; - } - else - { - break; - } - } - qsort( active_edges, n_active_edges, sizeof(*active_edges), Edge::CompareX ); + int n_active_edges = 0; + Edge active_edges[n_global_edges]; + int y = global_edges[0].min_y; + do + { + for ( int i = 0; i < n_global_edges; i++ ) + { + if ( global_edges[i].min_y == y ) + { + Debug( 9, "Moving global edge" ); + active_edges[n_active_edges++] = global_edges[i]; + if ( i < (n_global_edges-1) ) + { + //memcpy( &global_edges[i], &global_edges[i+1], sizeof(*global_edges)*(n_global_edges-i) ); + memmove( &global_edges[i], &global_edges[i+1], sizeof(*global_edges)*(n_global_edges-i) ); + i--; + } + n_global_edges--; + } + else + { + break; + } + } + qsort( active_edges, n_active_edges, sizeof(*active_edges), Edge::CompareX ); #ifndef ZM_DBG_OFF - if ( logLevel() >= Logger::DEBUG9 ) - { - for ( int i = 0; i < n_active_edges; i++ ) - { - Debug( 9, "%d - %d: min_y: %d, max_y:%d, min_x:%.2f, 1/m:%.2f", y, i, active_edges[i].min_y, active_edges[i].max_y, active_edges[i].min_x, active_edges[i]._1_m ); - } - } + if ( logLevel() >= Logger::DEBUG9 ) + { + for ( int i = 0; i < n_active_edges; i++ ) + { + Debug( 9, "%d - %d: min_y: %d, max_y:%d, min_x:%.2f, 1/m:%.2f", y, i, active_edges[i].min_y, active_edges[i].max_y, active_edges[i].min_x, active_edges[i]._1_m ); + } + } #endif - if ( !(y%density) ) - { - //Debug( 9, "%d", y ); - for ( int i = 0; i < n_active_edges; ) - { - int lo_x = int(round(active_edges[i++].min_x)); - int hi_x = int(round(active_edges[i++].min_x)); - if( colours == ZM_COLOUR_GRAY8 ) { - unsigned char *p = &buffer[(y*width)+lo_x]; - for ( int x = lo_x; x <= hi_x; x++, p++) - { - if ( !(x%density) ) - { - //Debug( 9, " %d", x ); - *p = colour; - } - } - } else if( colours == ZM_COLOUR_RGB24 ) { - unsigned char *p = &buffer[colours*((y*width)+lo_x)]; - for ( int x = lo_x; x <= hi_x; x++, p += 3) - { - if ( !(x%density) ) - { - RED_PTR_RGBA(p) = RED_VAL_RGBA(colour); - GREEN_PTR_RGBA(p) = GREEN_VAL_RGBA(colour); - BLUE_PTR_RGBA(p) = BLUE_VAL_RGBA(colour); - } - } - } else if( colours == ZM_COLOUR_RGB32 ) { - Rgb *p = (Rgb*)&buffer[((y*width)+lo_x)<<2]; - for ( int x = lo_x; x <= hi_x; x++, p++) - { - if ( !(x%density) ) - { - /* Fast, copies the entire pixel in a single pass */ - *p = colour; - } - } - } - } - } - y++; - for ( int i = n_active_edges-1; i >= 0; i-- ) - { - if ( y >= active_edges[i].max_y ) // Or >= as per sheets - { - Debug( 9, "Deleting active_edge" ); - if ( i < (n_active_edges-1) ) - { - //memcpy( &active_edges[i], &active_edges[i+1], sizeof(*active_edges)*(n_active_edges-i) ); - memmove( &active_edges[i], &active_edges[i+1], sizeof(*active_edges)*(n_active_edges-i) ); - } - n_active_edges--; - } - else - { - active_edges[i].min_x += active_edges[i]._1_m; - } - } - } while ( n_global_edges || n_active_edges ); + if ( !(y%density) ) + { + //Debug( 9, "%d", y ); + for ( int i = 0; i < n_active_edges; ) + { + int lo_x = int(round(active_edges[i++].min_x)); + int hi_x = int(round(active_edges[i++].min_x)); + if( colours == ZM_COLOUR_GRAY8 ) { + unsigned char *p = &buffer[(y*width)+lo_x]; + for ( int x = lo_x; x <= hi_x; x++, p++) + { + if ( !(x%density) ) + { + //Debug( 9, " %d", x ); + *p = colour; + } + } + } else if( colours == ZM_COLOUR_RGB24 ) { + unsigned char *p = &buffer[colours*((y*width)+lo_x)]; + for ( int x = lo_x; x <= hi_x; x++, p += 3) + { + if ( !(x%density) ) + { + RED_PTR_RGBA(p) = RED_VAL_RGBA(colour); + GREEN_PTR_RGBA(p) = GREEN_VAL_RGBA(colour); + BLUE_PTR_RGBA(p) = BLUE_VAL_RGBA(colour); + } + } + } else if( colours == ZM_COLOUR_RGB32 ) { + Rgb *p = (Rgb*)&buffer[((y*width)+lo_x)<<2]; + for ( int x = lo_x; x <= hi_x; x++, p++) + { + if ( !(x%density) ) + { + /* Fast, copies the entire pixel in a single pass */ + *p = colour; + } + } + } + } + } + y++; + for ( int i = n_active_edges-1; i >= 0; i-- ) + { + if ( y >= active_edges[i].max_y ) // Or >= as per sheets + { + Debug( 9, "Deleting active_edge" ); + if ( i < (n_active_edges-1) ) + { + //memcpy( &active_edges[i], &active_edges[i+1], sizeof(*active_edges)*(n_active_edges-i) ); + memmove( &active_edges[i], &active_edges[i+1], sizeof(*active_edges)*(n_active_edges-i) ); + } + n_active_edges--; + } + else + { + active_edges[i].min_x += active_edges[i]._1_m; + } + } + } while ( n_global_edges || n_active_edges ); } void Image::Fill( Rgb colour, const Polygon &polygon ) { - Fill( colour, 1, polygon ); + Fill( colour, 1, polygon ); } /* RGB32 compatible: complete */ void Image::Rotate( int angle ) { - - angle %= 360; + + angle %= 360; - if ( !angle ) - { - return; - } - if ( angle%90 ) - { - return; - } - - unsigned int new_height = height; - unsigned int new_width = width; - uint8_t* rotate_buffer = AllocBuffer(size); + if ( !angle ) + { + return; + } + if ( angle%90 ) + { + return; + } + + unsigned int new_height = height; + unsigned int new_width = width; + uint8_t* rotate_buffer = AllocBuffer(size); - switch( angle ) - { - case 90 : - { - new_height = width; - new_width = height; + switch( angle ) + { + case 90 : + { + new_height = width; + new_width = height; - unsigned int line_bytes = new_width*colours; - unsigned char *s_ptr = buffer; + unsigned int line_bytes = new_width*colours; + unsigned char *s_ptr = buffer; - if ( colours == ZM_COLOUR_GRAY8 ) - { - unsigned char *d_ptr; - for ( unsigned int i = new_width; i > 0; i-- ) - { - d_ptr = rotate_buffer+(i-1); - for ( unsigned int j = new_height; j > 0; j-- ) - { - *d_ptr = *s_ptr++; - d_ptr += line_bytes; - } - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - Rgb* s_rptr = (Rgb*)s_ptr; - Rgb* d_rptr; - for ( unsigned int i = new_width; i > 0; i-- ) - { - d_rptr = (Rgb*)(rotate_buffer+((i-1)<<2)); - for ( unsigned int j = new_height; j > 0; j-- ) - { - *d_rptr = *s_rptr++; - d_rptr += new_width; - } - } - } - else /* Assume RGB24 */ - { - unsigned char *d_ptr; - for ( unsigned int i = new_width; i > 0; i-- ) - { - d_ptr = rotate_buffer+((i-1)*3); - for ( unsigned int j = new_height; j > 0; j-- ) - { - *d_ptr = *s_ptr++; - *(d_ptr+1) = *s_ptr++; - *(d_ptr+2) = *s_ptr++; - d_ptr += line_bytes; - } - } - } - break; - } - case 180 : - { - unsigned char *s_ptr = buffer+size; - unsigned char *d_ptr = rotate_buffer; + if ( colours == ZM_COLOUR_GRAY8 ) + { + unsigned char *d_ptr; + for ( unsigned int i = new_width; i > 0; i-- ) + { + d_ptr = rotate_buffer+(i-1); + for ( unsigned int j = new_height; j > 0; j-- ) + { + *d_ptr = *s_ptr++; + d_ptr += line_bytes; + } + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + Rgb* s_rptr = (Rgb*)s_ptr; + Rgb* d_rptr; + for ( unsigned int i = new_width; i > 0; i-- ) + { + d_rptr = (Rgb*)(rotate_buffer+((i-1)<<2)); + for ( unsigned int j = new_height; j > 0; j-- ) + { + *d_rptr = *s_rptr++; + d_rptr += new_width; + } + } + } + else /* Assume RGB24 */ + { + unsigned char *d_ptr; + for ( unsigned int i = new_width; i > 0; i-- ) + { + d_ptr = rotate_buffer+((i-1)*3); + for ( unsigned int j = new_height; j > 0; j-- ) + { + *d_ptr = *s_ptr++; + *(d_ptr+1) = *s_ptr++; + *(d_ptr+2) = *s_ptr++; + d_ptr += line_bytes; + } + } + } + break; + } + case 180 : + { + unsigned char *s_ptr = buffer+size; + unsigned char *d_ptr = rotate_buffer; - if ( colours == ZM_COLOUR_GRAY8 ) - { - while( s_ptr > buffer ) - { - s_ptr--; - *d_ptr++ = *s_ptr; - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - Rgb* s_rptr = (Rgb*)s_ptr; - Rgb* d_rptr = (Rgb*)d_ptr; - while( s_rptr > (Rgb*)buffer ) - { - s_rptr--; - *d_rptr++ = *s_rptr; - } - } - else /* Assume RGB24 */ - { - while( s_ptr > buffer ) - { - s_ptr -= 3; - *d_ptr++ = *s_ptr; - *d_ptr++ = *(s_ptr+1); - *d_ptr++ = *(s_ptr+2); - } - } - break; - } - case 270 : - { - new_height = width; - new_width = height; + if ( colours == ZM_COLOUR_GRAY8 ) + { + while( s_ptr > buffer ) + { + s_ptr--; + *d_ptr++ = *s_ptr; + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + Rgb* s_rptr = (Rgb*)s_ptr; + Rgb* d_rptr = (Rgb*)d_ptr; + while( s_rptr > (Rgb*)buffer ) + { + s_rptr--; + *d_rptr++ = *s_rptr; + } + } + else /* Assume RGB24 */ + { + while( s_ptr > buffer ) + { + s_ptr -= 3; + *d_ptr++ = *s_ptr; + *d_ptr++ = *(s_ptr+1); + *d_ptr++ = *(s_ptr+2); + } + } + break; + } + case 270 : + { + new_height = width; + new_width = height; - unsigned int line_bytes = new_width*colours; - unsigned char *s_ptr = buffer+size; + unsigned int line_bytes = new_width*colours; + unsigned char *s_ptr = buffer+size; - if ( colours == ZM_COLOUR_GRAY8 ) - { - unsigned char *d_ptr; - for ( unsigned int i = new_width; i > 0; i-- ) - { - d_ptr = rotate_buffer+(i-1); - for ( unsigned int j = new_height; j > 0; j-- ) - { - s_ptr--; - *d_ptr = *s_ptr; - d_ptr += line_bytes; - } - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - Rgb* s_rptr = (Rgb*)s_ptr; - Rgb* d_rptr; - for ( unsigned int i = new_width; i > 0; i-- ) - { - d_rptr = (Rgb*)(rotate_buffer+((i-1)<<2)); - for ( unsigned int j = new_height; j > 0; j-- ) - { - s_rptr--; - *d_rptr = *s_rptr; - d_rptr += new_width; - } - } - } - else /* Assume RGB24 */ - { - unsigned char *d_ptr; - for ( unsigned int i = new_width; i > 0; i-- ) - { - d_ptr = rotate_buffer+((i-1)*3); - for ( unsigned int j = new_height; j > 0; j-- ) - { - *(d_ptr+2) = *(--s_ptr); - *(d_ptr+1) = *(--s_ptr); - *d_ptr = *(--s_ptr); - d_ptr += line_bytes; - } - } - } - break; - } - } + if ( colours == ZM_COLOUR_GRAY8 ) + { + unsigned char *d_ptr; + for ( unsigned int i = new_width; i > 0; i-- ) + { + d_ptr = rotate_buffer+(i-1); + for ( unsigned int j = new_height; j > 0; j-- ) + { + s_ptr--; + *d_ptr = *s_ptr; + d_ptr += line_bytes; + } + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + Rgb* s_rptr = (Rgb*)s_ptr; + Rgb* d_rptr; + for ( unsigned int i = new_width; i > 0; i-- ) + { + d_rptr = (Rgb*)(rotate_buffer+((i-1)<<2)); + for ( unsigned int j = new_height; j > 0; j-- ) + { + s_rptr--; + *d_rptr = *s_rptr; + d_rptr += new_width; + } + } + } + else /* Assume RGB24 */ + { + unsigned char *d_ptr; + for ( unsigned int i = new_width; i > 0; i-- ) + { + d_ptr = rotate_buffer+((i-1)*3); + for ( unsigned int j = new_height; j > 0; j-- ) + { + *(d_ptr+2) = *(--s_ptr); + *(d_ptr+1) = *(--s_ptr); + *d_ptr = *(--s_ptr); + d_ptr += line_bytes; + } + } + } + break; + } + } - AssignDirect( new_width, new_height, colours, subpixelorder, rotate_buffer, size, ZM_BUFTYPE_ZM); - + AssignDirect( new_width, new_height, colours, subpixelorder, rotate_buffer, size, ZM_BUFTYPE_ZM); + } /* RGB32 compatible: complete */ void Image::Flip( bool leftright ) { - uint8_t* flip_buffer = AllocBuffer(size); - - unsigned int line_bytes = width*colours; - unsigned int line_bytes2 = 2*line_bytes; - if ( leftright ) - { - // Horizontal flip, left to right - unsigned char *s_ptr = buffer+line_bytes; - unsigned char *d_ptr = flip_buffer; - unsigned char *max_d_ptr = flip_buffer + size; + uint8_t* flip_buffer = AllocBuffer(size); + + unsigned int line_bytes = width*colours; + unsigned int line_bytes2 = 2*line_bytes; + if ( leftright ) + { + // Horizontal flip, left to right + unsigned char *s_ptr = buffer+line_bytes; + unsigned char *d_ptr = flip_buffer; + unsigned char *max_d_ptr = flip_buffer + size; - if ( colours == ZM_COLOUR_GRAY8 ) - { - while( d_ptr < max_d_ptr ) - { - for ( unsigned int j = 0; j < width; j++ ) - { - s_ptr--; - *d_ptr++ = *s_ptr; - } - s_ptr += line_bytes2; - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - Rgb* s_rptr = (Rgb*)s_ptr; - Rgb* d_rptr = (Rgb*)flip_buffer; - Rgb* max_d_rptr = (Rgb*)max_d_ptr; - while( d_rptr < max_d_rptr ) - { - for ( unsigned int j = 0; j < width; j++ ) - { - s_rptr--; - *d_rptr++ = *s_rptr; - } - s_rptr += width * 2; - } - } - else /* Assume RGB24 */ - { - while( d_ptr < max_d_ptr ) - { - for ( unsigned int j = 0; j < width; j++ ) - { - s_ptr -= 3; - *d_ptr++ = *s_ptr; - *d_ptr++ = *(s_ptr+1); - *d_ptr++ = *(s_ptr+2); - } - s_ptr += line_bytes2; - } - } - } - else - { - // Vertical flip, top to bottom - unsigned char *s_ptr = buffer+(height*line_bytes); - unsigned char *d_ptr = flip_buffer; + if ( colours == ZM_COLOUR_GRAY8 ) + { + while( d_ptr < max_d_ptr ) + { + for ( unsigned int j = 0; j < width; j++ ) + { + s_ptr--; + *d_ptr++ = *s_ptr; + } + s_ptr += line_bytes2; + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + Rgb* s_rptr = (Rgb*)s_ptr; + Rgb* d_rptr = (Rgb*)flip_buffer; + Rgb* max_d_rptr = (Rgb*)max_d_ptr; + while( d_rptr < max_d_rptr ) + { + for ( unsigned int j = 0; j < width; j++ ) + { + s_rptr--; + *d_rptr++ = *s_rptr; + } + s_rptr += width * 2; + } + } + else /* Assume RGB24 */ + { + while( d_ptr < max_d_ptr ) + { + for ( unsigned int j = 0; j < width; j++ ) + { + s_ptr -= 3; + *d_ptr++ = *s_ptr; + *d_ptr++ = *(s_ptr+1); + *d_ptr++ = *(s_ptr+2); + } + s_ptr += line_bytes2; + } + } + } + else + { + // Vertical flip, top to bottom + unsigned char *s_ptr = buffer+(height*line_bytes); + unsigned char *d_ptr = flip_buffer; - while( s_ptr > buffer ) - { - s_ptr -= line_bytes; - memcpy( d_ptr, s_ptr, line_bytes ); - d_ptr += line_bytes; - } - } - - AssignDirect( width, height, colours, subpixelorder, flip_buffer, size, ZM_BUFTYPE_ZM); - + while( s_ptr > buffer ) + { + s_ptr -= line_bytes; + memcpy( d_ptr, s_ptr, line_bytes ); + d_ptr += line_bytes; + } + } + + AssignDirect( width, height, colours, subpixelorder, flip_buffer, size, ZM_BUFTYPE_ZM); + } void Image::Scale( unsigned int factor ) { - if ( !factor ) - { - Error( "Bogus scale factor %d found", factor ); - return; - } - if ( factor == ZM_SCALE_BASE ) - { - return; - } + if ( !factor ) + { + Error( "Bogus scale factor %d found", factor ); + return; + } + if ( factor == ZM_SCALE_BASE ) + { + return; + } - unsigned int new_width = (width*factor)/ZM_SCALE_BASE; - unsigned int new_height = (height*factor)/ZM_SCALE_BASE; - - size_t scale_buffer_size = (new_width+1) * (new_height+1) * colours; - - uint8_t* scale_buffer = AllocBuffer(scale_buffer_size); - - if ( factor > ZM_SCALE_BASE ) - { - unsigned char *pd = scale_buffer; - unsigned int wc = width*colours; - unsigned int nwc = new_width*colours; - unsigned int h_count = ZM_SCALE_BASE/2; - unsigned int last_h_index = 0; - unsigned int last_w_index = 0; - unsigned int h_index; - for ( unsigned int y = 0; y < height; y++ ) - { - unsigned char *ps = &buffer[y*wc]; - unsigned int w_count = ZM_SCALE_BASE/2; - unsigned int w_index; - last_w_index = 0; - for ( unsigned int x = 0; x < width; x++ ) - { - w_count += factor; - w_index = w_count/ZM_SCALE_BASE; - for (unsigned int f = last_w_index; f < w_index; f++ ) - { - for ( unsigned int c = 0; c < colours; c++ ) - { - *pd++ = *(ps+c); - } - } - ps += colours; - last_w_index = w_index; - } - h_count += factor; - h_index = h_count/ZM_SCALE_BASE; - for ( unsigned int f = last_h_index+1; f < h_index; f++ ) - { - memcpy( pd, pd-nwc, nwc ); - pd += nwc; - } - last_h_index = h_index; - } - new_width = last_w_index; - new_height = last_h_index; - } - else - { - unsigned char *pd = scale_buffer; - unsigned int wc = width*colours; - unsigned int xstart = factor/2; - unsigned int ystart = factor/2; - unsigned int h_count = ystart; - unsigned int last_h_index = 0; - unsigned int last_w_index = 0; - unsigned int h_index; - for ( unsigned int y = 0; y < (unsigned int)height; y++ ) - { - h_count += factor; - h_index = h_count/ZM_SCALE_BASE; - if ( h_index > last_h_index ) - { - unsigned int w_count = xstart; - unsigned int w_index; - last_w_index = 0; + unsigned int new_width = (width*factor)/ZM_SCALE_BASE; + unsigned int new_height = (height*factor)/ZM_SCALE_BASE; + + size_t scale_buffer_size = (new_width+1) * (new_height+1) * colours; + + uint8_t* scale_buffer = AllocBuffer(scale_buffer_size); + + if ( factor > ZM_SCALE_BASE ) + { + unsigned char *pd = scale_buffer; + unsigned int wc = width*colours; + unsigned int nwc = new_width*colours; + unsigned int h_count = ZM_SCALE_BASE/2; + unsigned int last_h_index = 0; + unsigned int last_w_index = 0; + unsigned int h_index; + for ( unsigned int y = 0; y < height; y++ ) + { + unsigned char *ps = &buffer[y*wc]; + unsigned int w_count = ZM_SCALE_BASE/2; + unsigned int w_index; + last_w_index = 0; + for ( unsigned int x = 0; x < width; x++ ) + { + w_count += factor; + w_index = w_count/ZM_SCALE_BASE; + for (unsigned int f = last_w_index; f < w_index; f++ ) + { + for ( unsigned int c = 0; c < colours; c++ ) + { + *pd++ = *(ps+c); + } + } + ps += colours; + last_w_index = w_index; + } + h_count += factor; + h_index = h_count/ZM_SCALE_BASE; + for ( unsigned int f = last_h_index+1; f < h_index; f++ ) + { + memcpy( pd, pd-nwc, nwc ); + pd += nwc; + } + last_h_index = h_index; + } + new_width = last_w_index; + new_height = last_h_index; + } + else + { + unsigned char *pd = scale_buffer; + unsigned int wc = width*colours; + unsigned int xstart = factor/2; + unsigned int ystart = factor/2; + unsigned int h_count = ystart; + unsigned int last_h_index = 0; + unsigned int last_w_index = 0; + unsigned int h_index; + for ( unsigned int y = 0; y < (unsigned int)height; y++ ) + { + h_count += factor; + h_index = h_count/ZM_SCALE_BASE; + if ( h_index > last_h_index ) + { + unsigned int w_count = xstart; + unsigned int w_index; + last_w_index = 0; - unsigned char *ps = &buffer[y*wc]; - for ( unsigned int x = 0; x < (unsigned int)width; x++ ) - { - w_count += factor; - w_index = w_count/ZM_SCALE_BASE; - - if ( w_index > last_w_index ) - { - for ( unsigned int c = 0; c < colours; c++ ) - { - *pd++ = *ps++; - } - } - else - { - ps += colours; - } - last_w_index = w_index; - } - } - last_h_index = h_index; - } - new_width = last_w_index; - new_height = last_h_index; - } - - AssignDirect( new_width, new_height, colours, subpixelorder, scale_buffer, scale_buffer_size, ZM_BUFTYPE_ZM); - + unsigned char *ps = &buffer[y*wc]; + for ( unsigned int x = 0; x < (unsigned int)width; x++ ) + { + w_count += factor; + w_index = w_count/ZM_SCALE_BASE; + + if ( w_index > last_w_index ) + { + for ( unsigned int c = 0; c < colours; c++ ) + { + *pd++ = *ps++; + } + } + else + { + ps += colours; + } + last_w_index = w_index; + } + } + last_h_index = h_index; + } + new_width = last_w_index; + new_height = last_h_index; + } + + AssignDirect( new_width, new_height, colours, subpixelorder, scale_buffer, scale_buffer_size, ZM_BUFTYPE_ZM); + } void Image::Deinterlace_Discard() { - /* Simple deinterlacing. Copy the even lines into the odd lines */ - - if ( colours == ZM_COLOUR_GRAY8 ) - { - const uint8_t *psrc; - uint8_t *pdest; - for (unsigned int y = 0; y < (unsigned int)height; y += 2) - { - psrc = buffer + (y * width); - pdest = buffer + ((y+1) * width); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pdest++ = *psrc++; - } - } - } - else if ( colours == ZM_COLOUR_RGB24 ) - { - const uint8_t *psrc; - uint8_t *pdest; - for (unsigned int y = 0; y < (unsigned int)height; y += 2) - { - psrc = buffer + ((y * width) * 3); - pdest = buffer + (((y+1) * width) * 3); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pdest++ = *psrc++; - *pdest++ = *psrc++; - *pdest++ = *psrc++; - } - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - const Rgb *psrc; - Rgb *pdest; - for (unsigned int y = 0; y < (unsigned int)height; y += 2) - { - psrc = (Rgb*)(buffer + ((y * width) << 2)); - pdest = (Rgb*)(buffer + (((y+1) * width) << 2)); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pdest++ = *psrc++; - } - } - } else { - Error("Deinterlace called with unexpected colours: %d", colours); - } - + /* Simple deinterlacing. Copy the even lines into the odd lines */ + + if ( colours == ZM_COLOUR_GRAY8 ) + { + const uint8_t *psrc; + uint8_t *pdest; + for (unsigned int y = 0; y < (unsigned int)height; y += 2) + { + psrc = buffer + (y * width); + pdest = buffer + ((y+1) * width); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pdest++ = *psrc++; + } + } + } + else if ( colours == ZM_COLOUR_RGB24 ) + { + const uint8_t *psrc; + uint8_t *pdest; + for (unsigned int y = 0; y < (unsigned int)height; y += 2) + { + psrc = buffer + ((y * width) * 3); + pdest = buffer + (((y+1) * width) * 3); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pdest++ = *psrc++; + *pdest++ = *psrc++; + *pdest++ = *psrc++; + } + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + const Rgb *psrc; + Rgb *pdest; + for (unsigned int y = 0; y < (unsigned int)height; y += 2) + { + psrc = (Rgb*)(buffer + ((y * width) << 2)); + pdest = (Rgb*)(buffer + (((y+1) * width) << 2)); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pdest++ = *psrc++; + } + } + } else { + Error("Deinterlace called with unexpected colours: %d", colours); + } + } void Image::Deinterlace_Linear() { - /* Simple deinterlacing. The odd lines are average of the line above and line below */ - - const uint8_t *pbelow, *pabove; - uint8_t *pcurrent; - - if ( colours == ZM_COLOUR_GRAY8 ) - { - for (unsigned int y = 1; y < (unsigned int)(height-1); y += 2) - { - pabove = buffer + ((y-1) * width); - pbelow = buffer + ((y+1) * width); - pcurrent = buffer + (y * width); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pcurrent++ = (*pabove++ + *pbelow++) >> 1; - } - } - /* Special case for the last line */ - pcurrent = buffer + ((height-1) * width); - pabove = buffer + ((height-2) * width); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pcurrent++ = *pabove++; - } - } - else if ( colours == ZM_COLOUR_RGB24 ) - { - for (unsigned int y = 1; y < (unsigned int)(height-1); y += 2) - { - pabove = buffer + (((y-1) * width) * 3); - pbelow = buffer + (((y+1) * width) * 3); - pcurrent = buffer + ((y * width) * 3); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pcurrent++ = (*pabove++ + *pbelow++) >> 1; - *pcurrent++ = (*pabove++ + *pbelow++) >> 1; - *pcurrent++ = (*pabove++ + *pbelow++) >> 1; - } - } - /* Special case for the last line */ - pcurrent = buffer + (((height-1) * width) * 3); - pabove = buffer + (((height-2) * width) * 3); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pcurrent++ = *pabove++; - *pcurrent++ = *pabove++; - *pcurrent++ = *pabove++; - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - for (unsigned int y = 1; y < (unsigned int)(height-1); y += 2) - { - pabove = buffer + (((y-1) * width) << 2); - pbelow = buffer + (((y+1) * width) << 2); - pcurrent = buffer + ((y * width) << 2); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pcurrent++ = (*pabove++ + *pbelow++) >> 1; - *pcurrent++ = (*pabove++ + *pbelow++) >> 1; - *pcurrent++ = (*pabove++ + *pbelow++) >> 1; - *pcurrent++ = (*pabove++ + *pbelow++) >> 1; - } - } - /* Special case for the last line */ - pcurrent = buffer + (((height-1) * width) << 2); - pabove = buffer + (((height-2) * width) << 2); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pcurrent++ = *pabove++; - *pcurrent++ = *pabove++; - *pcurrent++ = *pabove++; - *pcurrent++ = *pabove++; - } - } else { - Error("Deinterlace called with unexpected colours: %d", colours); - } - + /* Simple deinterlacing. The odd lines are average of the line above and line below */ + + const uint8_t *pbelow, *pabove; + uint8_t *pcurrent; + + if ( colours == ZM_COLOUR_GRAY8 ) + { + for (unsigned int y = 1; y < (unsigned int)(height-1); y += 2) + { + pabove = buffer + ((y-1) * width); + pbelow = buffer + ((y+1) * width); + pcurrent = buffer + (y * width); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pcurrent++ = (*pabove++ + *pbelow++) >> 1; + } + } + /* Special case for the last line */ + pcurrent = buffer + ((height-1) * width); + pabove = buffer + ((height-2) * width); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pcurrent++ = *pabove++; + } + } + else if ( colours == ZM_COLOUR_RGB24 ) + { + for (unsigned int y = 1; y < (unsigned int)(height-1); y += 2) + { + pabove = buffer + (((y-1) * width) * 3); + pbelow = buffer + (((y+1) * width) * 3); + pcurrent = buffer + ((y * width) * 3); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pcurrent++ = (*pabove++ + *pbelow++) >> 1; + *pcurrent++ = (*pabove++ + *pbelow++) >> 1; + *pcurrent++ = (*pabove++ + *pbelow++) >> 1; + } + } + /* Special case for the last line */ + pcurrent = buffer + (((height-1) * width) * 3); + pabove = buffer + (((height-2) * width) * 3); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pcurrent++ = *pabove++; + *pcurrent++ = *pabove++; + *pcurrent++ = *pabove++; + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + for (unsigned int y = 1; y < (unsigned int)(height-1); y += 2) + { + pabove = buffer + (((y-1) * width) << 2); + pbelow = buffer + (((y+1) * width) << 2); + pcurrent = buffer + ((y * width) << 2); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pcurrent++ = (*pabove++ + *pbelow++) >> 1; + *pcurrent++ = (*pabove++ + *pbelow++) >> 1; + *pcurrent++ = (*pabove++ + *pbelow++) >> 1; + *pcurrent++ = (*pabove++ + *pbelow++) >> 1; + } + } + /* Special case for the last line */ + pcurrent = buffer + (((height-1) * width) << 2); + pabove = buffer + (((height-2) * width) << 2); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pcurrent++ = *pabove++; + *pcurrent++ = *pabove++; + *pcurrent++ = *pabove++; + *pcurrent++ = *pabove++; + } + } else { + Error("Deinterlace called with unexpected colours: %d", colours); + } + } void Image::Deinterlace_Blend() { - /* Simple deinterlacing. Blend the fields together. 50% blend */ - - uint8_t *pabove, *pcurrent; - - if ( colours == ZM_COLOUR_GRAY8 ) - { - for (unsigned int y = 1; y < (unsigned int)height; y += 2) - { - pabove = buffer + ((y-1) * width); - pcurrent = buffer + (y * width); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pabove = (*pabove + *pcurrent) >> 1; - *pcurrent++ = *pabove++; - } - } - } - else if ( colours == ZM_COLOUR_RGB24 ) - { - for (unsigned int y = 1; y < (unsigned int)height; y += 2) - { - pabove = buffer + (((y-1) * width) * 3); - pcurrent = buffer + ((y * width) * 3); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pabove = (*pabove + *pcurrent) >> 1; - *pcurrent++ = *pabove++; - *pabove = (*pabove + *pcurrent) >> 1; - *pcurrent++ = *pabove++; - *pabove = (*pabove + *pcurrent) >> 1; - *pcurrent++ = *pabove++; - } - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - for (unsigned int y = 1; y < (unsigned int)height; y += 2) - { - pabove = buffer + (((y-1) * width) << 2); - pcurrent = buffer + ((y * width) << 2); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - *pabove = (*pabove + *pcurrent) >> 1; - *pcurrent++ = *pabove++; - *pabove = (*pabove + *pcurrent) >> 1; - *pcurrent++ = *pabove++; - *pabove = (*pabove + *pcurrent) >> 1; - *pcurrent++ = *pabove++; - *pabove = (*pabove + *pcurrent) >> 1; - *pcurrent++ = *pabove++; - } - } - } else { - Error("Deinterlace called with unexpected colours: %d", colours); - } - + /* Simple deinterlacing. Blend the fields together. 50% blend */ + + uint8_t *pabove, *pcurrent; + + if ( colours == ZM_COLOUR_GRAY8 ) + { + for (unsigned int y = 1; y < (unsigned int)height; y += 2) + { + pabove = buffer + ((y-1) * width); + pcurrent = buffer + (y * width); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pabove = (*pabove + *pcurrent) >> 1; + *pcurrent++ = *pabove++; + } + } + } + else if ( colours == ZM_COLOUR_RGB24 ) + { + for (unsigned int y = 1; y < (unsigned int)height; y += 2) + { + pabove = buffer + (((y-1) * width) * 3); + pcurrent = buffer + ((y * width) * 3); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pabove = (*pabove + *pcurrent) >> 1; + *pcurrent++ = *pabove++; + *pabove = (*pabove + *pcurrent) >> 1; + *pcurrent++ = *pabove++; + *pabove = (*pabove + *pcurrent) >> 1; + *pcurrent++ = *pabove++; + } + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + for (unsigned int y = 1; y < (unsigned int)height; y += 2) + { + pabove = buffer + (((y-1) * width) << 2); + pcurrent = buffer + ((y * width) << 2); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + *pabove = (*pabove + *pcurrent) >> 1; + *pcurrent++ = *pabove++; + *pabove = (*pabove + *pcurrent) >> 1; + *pcurrent++ = *pabove++; + *pabove = (*pabove + *pcurrent) >> 1; + *pcurrent++ = *pabove++; + *pabove = (*pabove + *pcurrent) >> 1; + *pcurrent++ = *pabove++; + } + } + } else { + Error("Deinterlace called with unexpected colours: %d", colours); + } + } void Image::Deinterlace_Blend_CustomRatio(int divider) { - /* Simple deinterlacing. Blend the fields together at a custom ratio. */ - /* 1 = 50% blending */ - /* 2 = 25% blending */ - /* 3 = 12.% blending */ - /* 4 = 6.25% blending */ - - uint8_t *pabove, *pcurrent; - uint8_t subpix1, subpix2; - - if ( divider < 1 || divider > 4 ) { - Error("Deinterlace called with invalid blend ratio"); - } - - if ( colours == ZM_COLOUR_GRAY8 ) - { - for (unsigned int y = 1; y < (unsigned int)height; y += 2) - { - pabove = buffer + ((y-1) * width); - pcurrent = buffer + (y * width); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; - subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; - *pcurrent++ = subpix1; - *pabove++ = subpix2; - } - } - } - else if ( colours == ZM_COLOUR_RGB24 ) - { - for (unsigned int y = 1; y < (unsigned int)height; y += 2) - { - pabove = buffer + (((y-1) * width) * 3); - pcurrent = buffer + ((y * width) * 3); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; - subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; - *pcurrent++ = subpix1; - *pabove++ = subpix2; - subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; - subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; - *pcurrent++ = subpix1; - *pabove++ = subpix2; - subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; - subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; - *pcurrent++ = subpix1; - *pabove++ = subpix2; - } - } - } - else if ( colours == ZM_COLOUR_RGB32 ) - { - for (unsigned int y = 1; y < (unsigned int)height; y += 2) - { - pabove = buffer + (((y-1) * width) << 2); - pcurrent = buffer + ((y * width) << 2); - for (unsigned int x = 0; x < (unsigned int)width; x++) { - subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; - subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; - *pcurrent++ = subpix1; - *pabove++ = subpix2; - subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; - subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; - *pcurrent++ = subpix1; - *pabove++ = subpix2; - subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; - subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; - *pcurrent++ = subpix1; - *pabove++ = subpix2; - subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; - subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; - *pcurrent++ = subpix1; - *pabove++ = subpix2; - } - } - } else { - Error("Deinterlace called with unexpected colours: %d", colours); - } - + /* Simple deinterlacing. Blend the fields together at a custom ratio. */ + /* 1 = 50% blending */ + /* 2 = 25% blending */ + /* 3 = 12.% blending */ + /* 4 = 6.25% blending */ + + uint8_t *pabove, *pcurrent; + uint8_t subpix1, subpix2; + + if ( divider < 1 || divider > 4 ) { + Error("Deinterlace called with invalid blend ratio"); + } + + if ( colours == ZM_COLOUR_GRAY8 ) + { + for (unsigned int y = 1; y < (unsigned int)height; y += 2) + { + pabove = buffer + ((y-1) * width); + pcurrent = buffer + (y * width); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; + subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; + *pcurrent++ = subpix1; + *pabove++ = subpix2; + } + } + } + else if ( colours == ZM_COLOUR_RGB24 ) + { + for (unsigned int y = 1; y < (unsigned int)height; y += 2) + { + pabove = buffer + (((y-1) * width) * 3); + pcurrent = buffer + ((y * width) * 3); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; + subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; + *pcurrent++ = subpix1; + *pabove++ = subpix2; + subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; + subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; + *pcurrent++ = subpix1; + *pabove++ = subpix2; + subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; + subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; + *pcurrent++ = subpix1; + *pabove++ = subpix2; + } + } + } + else if ( colours == ZM_COLOUR_RGB32 ) + { + for (unsigned int y = 1; y < (unsigned int)height; y += 2) + { + pabove = buffer + (((y-1) * width) << 2); + pcurrent = buffer + ((y * width) << 2); + for (unsigned int x = 0; x < (unsigned int)width; x++) { + subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; + subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; + *pcurrent++ = subpix1; + *pabove++ = subpix2; + subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; + subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; + *pcurrent++ = subpix1; + *pabove++ = subpix2; + subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; + subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; + *pcurrent++ = subpix1; + *pabove++ = subpix2; + subpix1 = ((*pabove - *pcurrent)>>divider) + *pcurrent; + subpix2 = ((*pcurrent - *pabove)>>divider) + *pabove; + *pcurrent++ = subpix1; + *pabove++ = subpix2; + } + } + } else { + Error("Deinterlace called with unexpected colours: %d", colours); + } + } void Image::Deinterlace_4Field(const Image* next_image, unsigned int threshold) { - if ( !(width == next_image->width && height == next_image->height && colours == next_image->colours && subpixelorder == next_image->subpixelorder) ) - { - Panic( "Attempt to deinterlace different sized images, expected %dx%dx%d %d, got %dx%dx%d %d", width, height, colours, subpixelorder, next_image->width, next_image->height, next_image->colours, next_image->subpixelorder); - } - - switch(colours) { - case ZM_COLOUR_RGB24: - { - if(subpixelorder == ZM_SUBPIX_ORDER_BGR) { - /* BGR subpixel order */ - std_deinterlace_4field_bgr(buffer, next_image->buffer, threshold, width, height); - } else { - /* Assume RGB subpixel order */ - std_deinterlace_4field_rgb(buffer, next_image->buffer, threshold, width, height); - } - break; - } - case ZM_COLOUR_RGB32: - { - if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) { - /* ARGB subpixel order */ - (*fptr_deinterlace_4field_argb)(buffer, next_image->buffer, threshold, width, height); - } else if(subpixelorder == ZM_SUBPIX_ORDER_ABGR) { - /* ABGR subpixel order */ - (*fptr_deinterlace_4field_abgr)(buffer, next_image->buffer, threshold, width, height); - } else if(subpixelorder == ZM_SUBPIX_ORDER_BGRA) { - /* BGRA subpixel order */ - (*fptr_deinterlace_4field_bgra)(buffer, next_image->buffer, threshold, width, height); - } else { - /* Assume RGBA subpixel order */ - (*fptr_deinterlace_4field_rgba)(buffer, next_image->buffer, threshold, width, height); - } - break; - } - case ZM_COLOUR_GRAY8: - (*fptr_deinterlace_4field_gray8)(buffer, next_image->buffer, threshold, width, height); - break; - default: - Panic("Deinterlace_4Field called with unexpected colours: %d",colours); - break; - } - + if ( !(width == next_image->width && height == next_image->height && colours == next_image->colours && subpixelorder == next_image->subpixelorder) ) + { + Panic( "Attempt to deinterlace different sized images, expected %dx%dx%d %d, got %dx%dx%d %d", width, height, colours, subpixelorder, next_image->width, next_image->height, next_image->colours, next_image->subpixelorder); + } + + switch(colours) { + case ZM_COLOUR_RGB24: + { + if(subpixelorder == ZM_SUBPIX_ORDER_BGR) { + /* BGR subpixel order */ + std_deinterlace_4field_bgr(buffer, next_image->buffer, threshold, width, height); + } else { + /* Assume RGB subpixel order */ + std_deinterlace_4field_rgb(buffer, next_image->buffer, threshold, width, height); + } + break; + } + case ZM_COLOUR_RGB32: + { + if(subpixelorder == ZM_SUBPIX_ORDER_ARGB) { + /* ARGB subpixel order */ + (*fptr_deinterlace_4field_argb)(buffer, next_image->buffer, threshold, width, height); + } else if(subpixelorder == ZM_SUBPIX_ORDER_ABGR) { + /* ABGR subpixel order */ + (*fptr_deinterlace_4field_abgr)(buffer, next_image->buffer, threshold, width, height); + } else if(subpixelorder == ZM_SUBPIX_ORDER_BGRA) { + /* BGRA subpixel order */ + (*fptr_deinterlace_4field_bgra)(buffer, next_image->buffer, threshold, width, height); + } else { + /* Assume RGBA subpixel order */ + (*fptr_deinterlace_4field_rgba)(buffer, next_image->buffer, threshold, width, height); + } + break; + } + case ZM_COLOUR_GRAY8: + (*fptr_deinterlace_4field_gray8)(buffer, next_image->buffer, threshold, width, height); + break; + default: + Panic("Deinterlace_4Field called with unexpected colours: %d",colours); + break; + } + } @@ -3124,343 +3124,343 @@ __attribute__((noinline,__target__("sse2"))) #endif void sse2_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - static uint32_t divider = 0; - static uint32_t clearmask = 0; - static double current_blendpercent = 0.0; - - if(current_blendpercent != blendpercent) { - /* Attempt to match the blending percent to one of the possible values */ - if(blendpercent < 2.34375) { - // 1.5625% blending - divider = 6; - clearmask = 0x03030303; - } else if(blendpercent < 4.6875) { - // 3.125% blending - divider = 5; - clearmask = 0x07070707; - } else if(blendpercent < 9.375) { - // 6.25% blending - divider = 4; - clearmask = 0x0F0F0F0F; - } else if(blendpercent < 18.75) { - // 12.5% blending - divider = 3; - clearmask = 0x1F1F1F1F; - } else if(blendpercent < 37.5) { - // 25% blending - divider = 2; - clearmask = 0x3F3F3F3F; - } else { - // 50% blending - divider = 1; - clearmask = 0x7F7F7F7F; - } - current_blendpercent = blendpercent; - } + static uint32_t divider = 0; + static uint32_t clearmask = 0; + static double current_blendpercent = 0.0; + + if(current_blendpercent != blendpercent) { + /* Attempt to match the blending percent to one of the possible values */ + if(blendpercent < 2.34375) { + // 1.5625% blending + divider = 6; + clearmask = 0x03030303; + } else if(blendpercent < 4.6875) { + // 3.125% blending + divider = 5; + clearmask = 0x07070707; + } else if(blendpercent < 9.375) { + // 6.25% blending + divider = 4; + clearmask = 0x0F0F0F0F; + } else if(blendpercent < 18.75) { + // 12.5% blending + divider = 3; + clearmask = 0x1F1F1F1F; + } else if(blendpercent < 37.5) { + // 25% blending + divider = 2; + clearmask = 0x3F3F3F3F; + } else { + // 50% blending + divider = 1; + clearmask = 0x7F7F7F7F; + } + current_blendpercent = blendpercent; + } - __asm__ __volatile__( - "movd %4, %%xmm3\n\t" - "movd %5, %%xmm4\n\t" - "pshufd $0x0, %%xmm3, %%xmm3\n\t" - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x10, %2\n\t" - "sse2_fastblend_iter:\n\t" - "movdqa (%0,%3),%%xmm0\n\t" - "movdqa %%xmm0,%%xmm2\n\t" - "movdqa (%1,%3),%%xmm1\n\t" - "psrlq %%xmm4,%%xmm0\n\t" - "psrlq %%xmm4,%%xmm1\n\t" - "pand %%xmm3,%%xmm1\n\t" - "pand %%xmm3,%%xmm0\n\t" - "psubb %%xmm0,%%xmm1\n\t" - "paddb %%xmm2,%%xmm1\n\t" - "movntdq %%xmm1,(%2,%3)\n\t" - "sub $0x10, %3\n\t" - "jnz sse2_fastblend_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (clearmask), "m" (divider) - : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "cc", "memory" - ); + __asm__ __volatile__( + "movd %4, %%xmm3\n\t" + "movd %5, %%xmm4\n\t" + "pshufd $0x0, %%xmm3, %%xmm3\n\t" + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x10, %2\n\t" + "sse2_fastblend_iter:\n\t" + "movdqa (%0,%3),%%xmm0\n\t" + "movdqa %%xmm0,%%xmm2\n\t" + "movdqa (%1,%3),%%xmm1\n\t" + "psrlq %%xmm4,%%xmm0\n\t" + "psrlq %%xmm4,%%xmm1\n\t" + "pand %%xmm3,%%xmm1\n\t" + "pand %%xmm3,%%xmm0\n\t" + "psubb %%xmm0,%%xmm1\n\t" + "paddb %%xmm2,%%xmm1\n\t" + "movntdq %%xmm1,(%2,%3)\n\t" + "sub $0x10, %3\n\t" + "jnz sse2_fastblend_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (clearmask), "m" (divider) + : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } __attribute__((noinline)) void std_fastblend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) { - static int divider = 0; - static double current_blendpercent = 0.0; - const uint8_t* const max_ptr = result + count; - - if(current_blendpercent != blendpercent) { - /* Attempt to match the blending percent to one of the possible values */ - if(blendpercent < 2.34375) { - // 1.5625% blending - divider = 6; - } else if(blendpercent < 4.6875) { - // 3.125% blending - divider = 5; - } else if(blendpercent < 9.375) { - // 6.25% blending - divider = 4; - } else if(blendpercent < 18.75) { - // 12.5% blending - divider = 3; - } else if(blendpercent < 37.5) { - // 25% blending - divider = 2; - } else { - // 50% blending - divider = 1; - } - current_blendpercent = blendpercent; - } - + static int divider = 0; + static double current_blendpercent = 0.0; + const uint8_t* const max_ptr = result + count; + + if(current_blendpercent != blendpercent) { + /* Attempt to match the blending percent to one of the possible values */ + if(blendpercent < 2.34375) { + // 1.5625% blending + divider = 6; + } else if(blendpercent < 4.6875) { + // 3.125% blending + divider = 5; + } else if(blendpercent < 9.375) { + // 6.25% blending + divider = 4; + } else if(blendpercent < 18.75) { + // 12.5% blending + divider = 3; + } else if(blendpercent < 37.5) { + // 25% blending + divider = 2; + } else { + // 50% blending + divider = 1; + } + current_blendpercent = blendpercent; + } + - while(result < max_ptr) { - result[0] = ((col2[0] - col1[0])>>divider) + col1[0]; - result[1] = ((col2[1] - col1[1])>>divider) + col1[1]; - result[2] = ((col2[2] - col1[2])>>divider) + col1[2]; - result[3] = ((col2[3] - col1[3])>>divider) + col1[3]; - result[4] = ((col2[4] - col1[4])>>divider) + col1[4]; - result[5] = ((col2[5] - col1[5])>>divider) + col1[5]; - result[6] = ((col2[6] - col1[6])>>divider) + col1[6]; - result[7] = ((col2[7] - col1[7])>>divider) + col1[7]; - result[8] = ((col2[8] - col1[8])>>divider) + col1[8]; - result[9] = ((col2[9] - col1[9])>>divider) + col1[9]; - result[10] = ((col2[10] - col1[10])>>divider) + col1[10]; - result[11] = ((col2[11] - col1[11])>>divider) + col1[11]; - result[12] = ((col2[12] - col1[12])>>divider) + col1[12]; - result[13] = ((col2[13] - col1[13])>>divider) + col1[13]; - result[14] = ((col2[14] - col1[14])>>divider) + col1[14]; - result[15] = ((col2[15] - col1[15])>>divider) + col1[15]; - - col1 += 16; - col2 += 16; - result += 16; - } + while(result < max_ptr) { + result[0] = ((col2[0] - col1[0])>>divider) + col1[0]; + result[1] = ((col2[1] - col1[1])>>divider) + col1[1]; + result[2] = ((col2[2] - col1[2])>>divider) + col1[2]; + result[3] = ((col2[3] - col1[3])>>divider) + col1[3]; + result[4] = ((col2[4] - col1[4])>>divider) + col1[4]; + result[5] = ((col2[5] - col1[5])>>divider) + col1[5]; + result[6] = ((col2[6] - col1[6])>>divider) + col1[6]; + result[7] = ((col2[7] - col1[7])>>divider) + col1[7]; + result[8] = ((col2[8] - col1[8])>>divider) + col1[8]; + result[9] = ((col2[9] - col1[9])>>divider) + col1[9]; + result[10] = ((col2[10] - col1[10])>>divider) + col1[10]; + result[11] = ((col2[11] - col1[11])>>divider) + col1[11]; + result[12] = ((col2[12] - col1[12])>>divider) + col1[12]; + result[13] = ((col2[13] - col1[13])>>divider) + col1[13]; + result[14] = ((col2[14] - col1[14])>>divider) + col1[14]; + result[15] = ((col2[15] - col1[15])>>divider) + col1[15]; + + col1 += 16; + col2 += 16; + result += 16; + } } __attribute__((noinline)) void std_blend(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count, double blendpercent) { - double divide = blendpercent / 100.0; - double opacity = 1.0 - divide; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - *result++ = (*col1++ * opacity) + (*col2++ * divide); - - } + double divide = blendpercent / 100.0; + double opacity = 1.0 - divide; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + *result++ = (*col1++ * opacity) + (*col2++ * divide); + + } } /************************************************* DELTA FUNCTIONS *************************************************/ /* Grayscale */ __attribute__((noinline)) void std_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { - /* Loop unrolling is used to work on 16 bytes (16 grayscale pixels) at a time */ - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - result[0] = abs(col1[0] - col2[0]); - result[1] = abs(col1[1] - col2[1]); - result[2] = abs(col1[2] - col2[2]); - result[3] = abs(col1[3] - col2[3]); - result[4] = abs(col1[4] - col2[4]); - result[5] = abs(col1[5] - col2[5]); - result[6] = abs(col1[6] - col2[6]); - result[7] = abs(col1[7] - col2[7]); - result[8] = abs(col1[8] - col2[8]); - result[9] = abs(col1[9] - col2[9]); - result[10] = abs(col1[10] - col2[10]); - result[11] = abs(col1[11] - col2[11]); - result[12] = abs(col1[12] - col2[12]); - result[13] = abs(col1[13] - col2[13]); - result[14] = abs(col1[14] - col2[14]); - result[15] = abs(col1[15] - col2[15]); - - col1 += 16; - col2 += 16; - result += 16; - } + /* Loop unrolling is used to work on 16 bytes (16 grayscale pixels) at a time */ + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + result[0] = abs(col1[0] - col2[0]); + result[1] = abs(col1[1] - col2[1]); + result[2] = abs(col1[2] - col2[2]); + result[3] = abs(col1[3] - col2[3]); + result[4] = abs(col1[4] - col2[4]); + result[5] = abs(col1[5] - col2[5]); + result[6] = abs(col1[6] - col2[6]); + result[7] = abs(col1[7] - col2[7]); + result[8] = abs(col1[8] - col2[8]); + result[9] = abs(col1[9] - col2[9]); + result[10] = abs(col1[10] - col2[10]); + result[11] = abs(col1[11] - col2[11]); + result[12] = abs(col1[12] - col2[12]); + result[13] = abs(col1[13] - col2[13]); + result[14] = abs(col1[14] - col2[14]); + result[15] = abs(col1[15] - col2[15]); + + col1 += 16; + col2 += 16; + result += 16; + } } /* RGB24: RGB */ __attribute__((noinline)) void std_delta8_rgb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { - /* Loop unrolling is used to work on 12 bytes (4 rgb24 pixels) at a time */ - int r,g,b; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - r = abs(col1[0] - col2[0]); - g = abs(col1[1] - col2[1]); - b = abs(col1[2] - col2[2]); - result[0] = (r + r + b + g + g + g + g + g)>>3; - r = abs(col1[3] - col2[3]); - g = abs(col1[4] - col2[4]); - b = abs(col1[5] - col2[5]); - result[1] = (r + r + b + g + g + g + g + g)>>3; - r = abs(col1[6] - col2[6]); - g = abs(col1[7] - col2[7]); - b = abs(col1[8] - col2[8]); - result[2] = (r + r + b + g + g + g + g + g)>>3; - r = abs(col1[9] - col2[9]); - g = abs(col1[10] - col2[10]); - b = abs(col1[11] - col2[11]); - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 12; - col2 += 12; - result += 4; - } + /* Loop unrolling is used to work on 12 bytes (4 rgb24 pixels) at a time */ + int r,g,b; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + r = abs(col1[0] - col2[0]); + g = abs(col1[1] - col2[1]); + b = abs(col1[2] - col2[2]); + result[0] = (r + r + b + g + g + g + g + g)>>3; + r = abs(col1[3] - col2[3]); + g = abs(col1[4] - col2[4]); + b = abs(col1[5] - col2[5]); + result[1] = (r + r + b + g + g + g + g + g)>>3; + r = abs(col1[6] - col2[6]); + g = abs(col1[7] - col2[7]); + b = abs(col1[8] - col2[8]); + result[2] = (r + r + b + g + g + g + g + g)>>3; + r = abs(col1[9] - col2[9]); + g = abs(col1[10] - col2[10]); + b = abs(col1[11] - col2[11]); + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 12; + col2 += 12; + result += 4; + } } /* RGB24: BGR */ __attribute__((noinline)) void std_delta8_bgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { - /* Loop unrolling is used to work on 12 bytes (4 rgb24 pixels) at a time */ - int r,g,b; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - b = abs(col1[0] - col2[0]); - g = abs(col1[1] - col2[1]); - r = abs(col1[2] - col2[2]); - result[0] = (r + r + b + g + g + g + g + g)>>3; - b = abs(col1[3] - col2[3]); - g = abs(col1[4] - col2[4]); - r = abs(col1[5] - col2[5]); - result[1] = (r + r + b + g + g + g + g + g)>>3; - b = abs(col1[6] - col2[6]); - g = abs(col1[7] - col2[7]); - r = abs(col1[8] - col2[8]); - result[2] = (r + r + b + g + g + g + g + g)>>3; - b = abs(col1[9] - col2[9]); - g = abs(col1[10] - col2[10]); - r = abs(col1[11] - col2[11]); - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 12; - col2 += 12; - result += 4; - } + /* Loop unrolling is used to work on 12 bytes (4 rgb24 pixels) at a time */ + int r,g,b; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + b = abs(col1[0] - col2[0]); + g = abs(col1[1] - col2[1]); + r = abs(col1[2] - col2[2]); + result[0] = (r + r + b + g + g + g + g + g)>>3; + b = abs(col1[3] - col2[3]); + g = abs(col1[4] - col2[4]); + r = abs(col1[5] - col2[5]); + result[1] = (r + r + b + g + g + g + g + g)>>3; + b = abs(col1[6] - col2[6]); + g = abs(col1[7] - col2[7]); + r = abs(col1[8] - col2[8]); + result[2] = (r + r + b + g + g + g + g + g)>>3; + b = abs(col1[9] - col2[9]); + g = abs(col1[10] - col2[10]); + r = abs(col1[11] - col2[11]); + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 12; + col2 += 12; + result += 4; + } } /* RGB32: RGBA */ __attribute__((noinline)) void std_delta8_rgba(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) { - r = abs(col1[0] - col2[0]); - g = abs(col1[1] - col2[1]); - b = abs(col1[2] - col2[2]); - result[0] = (r + r + b + g + g + g + g + g)>>3; - r = abs(col1[4] - col2[4]); - g = abs(col1[5] - col2[5]); - b = abs(col1[6] - col2[6]); - result[1] = (r + r + b + g + g + g + g + g)>>3; - r = abs(col1[8] - col2[8]); - g = abs(col1[9] - col2[9]); - b = abs(col1[10] - col2[10]); - result[2] = (r + r + b + g + g + g + g + g)>>3; - r = abs(col1[12] - col2[12]); - g = abs(col1[13] - col2[13]); - b = abs(col1[14] - col2[14]); - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 16; - col2 += 16; - result += 4; - } + /* 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) { + r = abs(col1[0] - col2[0]); + g = abs(col1[1] - col2[1]); + b = abs(col1[2] - col2[2]); + result[0] = (r + r + b + g + g + g + g + g)>>3; + r = abs(col1[4] - col2[4]); + g = abs(col1[5] - col2[5]); + b = abs(col1[6] - col2[6]); + result[1] = (r + r + b + g + g + g + g + g)>>3; + r = abs(col1[8] - col2[8]); + g = abs(col1[9] - col2[9]); + b = abs(col1[10] - col2[10]); + result[2] = (r + r + b + g + g + g + g + g)>>3; + r = abs(col1[12] - col2[12]); + g = abs(col1[13] - col2[13]); + b = abs(col1[14] - col2[14]); + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 16; + col2 += 16; + result += 4; + } } /* RGB32: BGRA */ __attribute__((noinline)) void std_delta8_bgra(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) { - b = abs(col1[0] - col2[0]); - g = abs(col1[1] - col2[1]); - r = abs(col1[2] - col2[2]); - result[0] = (r + r + b + g + g + g + g + g)>>3; - b = abs(col1[4] - col2[4]); - g = abs(col1[5] - col2[5]); - r = abs(col1[6] - col2[6]); - result[1] = (r + r + b + g + g + g + g + g)>>3; - b = abs(col1[8] - col2[8]); - g = abs(col1[9] - col2[9]); - r = abs(col1[10] - col2[10]); - result[2] = (r + r + b + g + g + g + g + g)>>3; - b = abs(col1[12] - col2[12]); - g = abs(col1[13] - col2[13]); - r = abs(col1[14] - col2[14]); - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 16; - col2 += 16; - result += 4; - } + /* 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) { + b = abs(col1[0] - col2[0]); + g = abs(col1[1] - col2[1]); + r = abs(col1[2] - col2[2]); + result[0] = (r + r + b + g + g + g + g + g)>>3; + b = abs(col1[4] - col2[4]); + g = abs(col1[5] - col2[5]); + r = abs(col1[6] - col2[6]); + result[1] = (r + r + b + g + g + g + g + g)>>3; + b = abs(col1[8] - col2[8]); + g = abs(col1[9] - col2[9]); + r = abs(col1[10] - col2[10]); + result[2] = (r + r + b + g + g + g + g + g)>>3; + b = abs(col1[12] - col2[12]); + g = abs(col1[13] - col2[13]); + r = abs(col1[14] - col2[14]); + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 16; + col2 += 16; + result += 4; + } } /* RGB32: ARGB */ __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) { - r = abs(col1[1] - col2[1]); - g = abs(col1[2] - col2[2]); - b = abs(col1[3] - col2[3]); - result[0] = (r + r + b + g + g + g + g + g)>>3; - r = abs(col1[5] - col2[5]); - g = abs(col1[6] - col2[6]); - b = abs(col1[7] - col2[7]); - result[1] = (r + r + b + g + g + g + g + g)>>3; - r = abs(col1[9] - col2[9]); - g = abs(col1[10] - col2[10]); - b = abs(col1[11] - col2[11]); - result[2] = (r + r + b + g + g + g + g + g)>>3; - r = abs(col1[13] - col2[13]); - g = abs(col1[14] - col2[14]); - b = abs(col1[15] - col2[15]); - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 16; - col2 += 16; - result += 4; - } + /* 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) { + r = abs(col1[1] - col2[1]); + g = abs(col1[2] - col2[2]); + b = abs(col1[3] - col2[3]); + result[0] = (r + r + b + g + g + g + g + g)>>3; + r = abs(col1[5] - col2[5]); + g = abs(col1[6] - col2[6]); + b = abs(col1[7] - col2[7]); + result[1] = (r + r + b + g + g + g + g + g)>>3; + r = abs(col1[9] - col2[9]); + g = abs(col1[10] - col2[10]); + b = abs(col1[11] - col2[11]); + result[2] = (r + r + b + g + g + g + g + g)>>3; + r = abs(col1[13] - col2[13]); + g = abs(col1[14] - col2[14]); + b = abs(col1[15] - col2[15]); + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 16; + col2 += 16; + result += 4; + } } /* RGB32: ABGR */ __attribute__((noinline)) void std_delta8_abgr(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) { - b = abs(col1[1] - col2[1]); - g = abs(col1[2] - col2[2]); - r = abs(col1[3] - col2[3]); - result[0] = (r + r + b + g + g + g + g + g)>>3; - b = abs(col1[5] - col2[5]); - g = abs(col1[6] - col2[6]); - r = abs(col1[7] - col2[7]); - result[1] = (r + r + b + g + g + g + g + g)>>3; - b = abs(col1[9] - col2[9]); - g = abs(col1[10] - col2[10]); - r = abs(col1[11] - col2[11]); - result[2] = (r + r + b + g + g + g + g + g)>>3; - b = abs(col1[13] - col2[13]); - g = abs(col1[14] - col2[14]); - r = abs(col1[15] - col2[15]); - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 16; - col2 += 16; - result += 4; - } + /* 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) { + b = abs(col1[1] - col2[1]); + g = abs(col1[2] - col2[2]); + r = abs(col1[3] - col2[3]); + result[0] = (r + r + b + g + g + g + g + g)>>3; + b = abs(col1[5] - col2[5]); + g = abs(col1[6] - col2[6]); + r = abs(col1[7] - col2[7]); + result[1] = (r + r + b + g + g + g + g + g)>>3; + b = abs(col1[9] - col2[9]); + g = abs(col1[10] - col2[10]); + r = abs(col1[11] - col2[11]); + result[2] = (r + r + b + g + g + g + g + g)>>3; + b = abs(col1[13] - col2[13]); + g = abs(col1[14] - col2[14]); + r = abs(col1[15] - col2[15]); + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 16; + col2 += 16; + result += 4; + } } /* Grayscale SSE2 */ @@ -3470,27 +3470,27 @@ __attribute__((noinline,__target__("sse2"))) void sse2_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __asm__ __volatile__ ( - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x10, %2\n\t" - "sse2_delta8_gray8_iter:\n\t" - "movdqa (%0,%3), %%xmm1\n\t" - "movdqa (%1,%3), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm3\n\t" - "movdqa %%xmm2, %%xmm4\n\t" - "pmaxub %%xmm1, %%xmm2\n\t" - "pminub %%xmm3, %%xmm4\n\t" - "psubb %%xmm4, %%xmm2\n\t" - "movntdq %%xmm2, (%2,%3)\n\t" - "sub $0x10, %3\n\t" - "jnz sse2_delta8_gray8_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count) - : "%xmm1", "%xmm2", "%xmm3", "%xmm4", "cc", "memory" - ); + __asm__ __volatile__ ( + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x10, %2\n\t" + "sse2_delta8_gray8_iter:\n\t" + "movdqa (%0,%3), %%xmm1\n\t" + "movdqa (%1,%3), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm3\n\t" + "movdqa %%xmm2, %%xmm4\n\t" + "pmaxub %%xmm1, %%xmm2\n\t" + "pminub %%xmm3, %%xmm4\n\t" + "psubb %%xmm4, %%xmm2\n\t" + "movntdq %%xmm2, (%2,%3)\n\t" + "sub $0x10, %3\n\t" + "jnz sse2_delta8_gray8_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count) + : "%xmm1", "%xmm2", "%xmm3", "%xmm4", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -3501,54 +3501,54 @@ __attribute__((noinline,__target__("sse2"))) void sse2_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "mov $0xff, %%eax\n\t" - "movd %%eax, %%xmm0\n\t" - "pshufd $0x0, %%xmm0, %%xmm0\n\t" - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x4, %2\n\t" - "sse2_delta8_rgba_iter:\n\t" - "movdqa (%0,%3,4), %%xmm1\n\t" - "movdqa (%1,%3,4), %%xmm2\n\t" - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" - "movdqa %%xmm2, %%xmm6\n\t" - "pmaxub %%xmm1, %%xmm2\n\t" - "pminub %%xmm5, %%xmm6\n\t" - "psubb %%xmm6, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm3\n\t" - "psrld $0x8, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "pslld $0x2, %%xmm2\n\t" - "paddd %%xmm1, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm1\n\t" - "pand %%xmm0, %%xmm1\n\t" - "paddd %%xmm1, %%xmm1\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x10, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "packssdw %%xmm1, %%xmm1\n\t" - "packuswb %%xmm1, %%xmm1\n\t" - "movd %%xmm1, %%eax\n\t" - "movnti %%eax, (%2,%3)\n\t" - "sub $0x4, %3\n\t" - "jnz sse2_delta8_rgba_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "cc", "memory" - ); + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "mov $0xff, %%eax\n\t" + "movd %%eax, %%xmm0\n\t" + "pshufd $0x0, %%xmm0, %%xmm0\n\t" + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x4, %2\n\t" + "sse2_delta8_rgba_iter:\n\t" + "movdqa (%0,%3,4), %%xmm1\n\t" + "movdqa (%1,%3,4), %%xmm2\n\t" + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" + "movdqa %%xmm2, %%xmm6\n\t" + "pmaxub %%xmm1, %%xmm2\n\t" + "pminub %%xmm5, %%xmm6\n\t" + "psubb %%xmm6, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm3\n\t" + "psrld $0x8, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "pslld $0x2, %%xmm2\n\t" + "paddd %%xmm1, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm1\n\t" + "pand %%xmm0, %%xmm1\n\t" + "paddd %%xmm1, %%xmm1\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x10, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "packssdw %%xmm1, %%xmm1\n\t" + "packuswb %%xmm1, %%xmm1\n\t" + "movd %%xmm1, %%eax\n\t" + "movnti %%eax, (%2,%3)\n\t" + "sub $0x4, %3\n\t" + "jnz sse2_delta8_rgba_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -3559,54 +3559,54 @@ __attribute__((noinline,__target__("sse2"))) void sse2_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "mov $0xff, %%eax\n\t" - "movd %%eax, %%xmm0\n\t" - "pshufd $0x0, %%xmm0, %%xmm0\n\t" - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x4, %2\n\t" - "sse2_delta8_bgra_iter:\n\t" - "movdqa (%0,%3,4), %%xmm1\n\t" - "movdqa (%1,%3,4), %%xmm2\n\t" - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" - "movdqa %%xmm2, %%xmm6\n\t" - "pmaxub %%xmm1, %%xmm2\n\t" - "pminub %%xmm5, %%xmm6\n\t" - "psubb %%xmm6, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm3\n\t" - "psrld $0x8, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "pslld $0x2, %%xmm2\n\t" - "paddd %%xmm1, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm1\n\t" - "pand %%xmm0, %%xmm1\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x10, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "paddd %%xmm2, %%xmm2\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "packssdw %%xmm1, %%xmm1\n\t" - "packuswb %%xmm1, %%xmm1\n\t" - "movd %%xmm1, %%eax\n\t" - "movnti %%eax, (%2,%3)\n\t" - "sub $0x4, %3\n\t" - "jnz sse2_delta8_bgra_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "cc", "memory" - ); + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "mov $0xff, %%eax\n\t" + "movd %%eax, %%xmm0\n\t" + "pshufd $0x0, %%xmm0, %%xmm0\n\t" + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x4, %2\n\t" + "sse2_delta8_bgra_iter:\n\t" + "movdqa (%0,%3,4), %%xmm1\n\t" + "movdqa (%1,%3,4), %%xmm2\n\t" + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" + "movdqa %%xmm2, %%xmm6\n\t" + "pmaxub %%xmm1, %%xmm2\n\t" + "pminub %%xmm5, %%xmm6\n\t" + "psubb %%xmm6, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm3\n\t" + "psrld $0x8, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "pslld $0x2, %%xmm2\n\t" + "paddd %%xmm1, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm1\n\t" + "pand %%xmm0, %%xmm1\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x10, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "paddd %%xmm2, %%xmm2\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "packssdw %%xmm1, %%xmm1\n\t" + "packuswb %%xmm1, %%xmm1\n\t" + "movd %%xmm1, %%eax\n\t" + "movnti %%eax, (%2,%3)\n\t" + "sub $0x4, %3\n\t" + "jnz sse2_delta8_bgra_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -3617,55 +3617,55 @@ __attribute__((noinline,__target__("sse2"))) void sse2_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "mov $0xff, %%eax\n\t" - "movd %%eax, %%xmm0\n\t" - "pshufd $0x0, %%xmm0, %%xmm0\n\t" - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x4, %2\n\t" - "sse2_delta8_argb_iter:\n\t" - "movdqa (%0,%3,4), %%xmm1\n\t" - "movdqa (%1,%3,4), %%xmm2\n\t" - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" - "movdqa %%xmm2, %%xmm6\n\t" - "pmaxub %%xmm1, %%xmm2\n\t" - "pminub %%xmm5, %%xmm6\n\t" - "psubb %%xmm6, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm3\n\t" - "psrld $0x10, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "pslld $0x2, %%xmm2\n\t" - "paddd %%xmm1, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm1\n\t" - "psrld $0x8, %%xmm1\n\t" - "pand %%xmm0, %%xmm1\n\t" - "paddd %%xmm1, %%xmm1\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x18, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "packssdw %%xmm1, %%xmm1\n\t" - "packuswb %%xmm1, %%xmm1\n\t" - "movd %%xmm1, %%eax\n\t" - "movnti %%eax, (%2,%3)\n\t" - "sub $0x4, %3\n\t" - "jnz sse2_delta8_argb_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "cc", "memory" - ); + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "mov $0xff, %%eax\n\t" + "movd %%eax, %%xmm0\n\t" + "pshufd $0x0, %%xmm0, %%xmm0\n\t" + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x4, %2\n\t" + "sse2_delta8_argb_iter:\n\t" + "movdqa (%0,%3,4), %%xmm1\n\t" + "movdqa (%1,%3,4), %%xmm2\n\t" + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" + "movdqa %%xmm2, %%xmm6\n\t" + "pmaxub %%xmm1, %%xmm2\n\t" + "pminub %%xmm5, %%xmm6\n\t" + "psubb %%xmm6, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm3\n\t" + "psrld $0x10, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "pslld $0x2, %%xmm2\n\t" + "paddd %%xmm1, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm1\n\t" + "psrld $0x8, %%xmm1\n\t" + "pand %%xmm0, %%xmm1\n\t" + "paddd %%xmm1, %%xmm1\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x18, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "packssdw %%xmm1, %%xmm1\n\t" + "packuswb %%xmm1, %%xmm1\n\t" + "movd %%xmm1, %%eax\n\t" + "movnti %%eax, (%2,%3)\n\t" + "sub $0x4, %3\n\t" + "jnz sse2_delta8_argb_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -3676,55 +3676,55 @@ __attribute__((noinline,__target__("sse2"))) void sse2_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "mov $0xff, %%eax\n\t" - "movd %%eax, %%xmm0\n\t" - "pshufd $0x0, %%xmm0, %%xmm0\n\t" - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x4, %2\n\t" - "sse2_delta8_abgr_iter:\n\t" - "movdqa (%0,%3,4), %%xmm1\n\t" - "movdqa (%1,%3,4), %%xmm2\n\t" - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" - "movdqa %%xmm2, %%xmm6\n\t" - "pmaxub %%xmm1, %%xmm2\n\t" - "pminub %%xmm5, %%xmm6\n\t" - "psubb %%xmm6, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm3\n\t" - "psrld $0x10, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "pslld $0x2, %%xmm2\n\t" - "paddd %%xmm1, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm1\n\t" - "psrld $0x8, %%xmm1\n\t" - "pand %%xmm0, %%xmm1\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x18, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "paddd %%xmm2, %%xmm2\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "packssdw %%xmm1, %%xmm1\n\t" - "packuswb %%xmm1, %%xmm1\n\t" - "movd %%xmm1, %%eax\n\t" - "movnti %%eax, (%2,%3)\n\t" - "sub $0x4, %3\n\t" - "jnz sse2_delta8_abgr_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "cc", "memory" - ); + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "mov $0xff, %%eax\n\t" + "movd %%eax, %%xmm0\n\t" + "pshufd $0x0, %%xmm0, %%xmm0\n\t" + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x4, %2\n\t" + "sse2_delta8_abgr_iter:\n\t" + "movdqa (%0,%3,4), %%xmm1\n\t" + "movdqa (%1,%3,4), %%xmm2\n\t" + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" + "movdqa %%xmm2, %%xmm6\n\t" + "pmaxub %%xmm1, %%xmm2\n\t" + "pminub %%xmm5, %%xmm6\n\t" + "psubb %%xmm6, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm3\n\t" + "psrld $0x10, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "pslld $0x2, %%xmm2\n\t" + "paddd %%xmm1, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm1\n\t" + "psrld $0x8, %%xmm1\n\t" + "pand %%xmm0, %%xmm1\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x18, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "paddd %%xmm2, %%xmm2\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "packssdw %%xmm1, %%xmm1\n\t" + "packuswb %%xmm1, %%xmm1\n\t" + "movd %%xmm1, %%eax\n\t" + "movnti %%eax, (%2,%3)\n\t" + "sub $0x4, %3\n\t" + "jnz sse2_delta8_abgr_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -3734,52 +3734,52 @@ __attribute__((noinline,__target__("ssse3"))) #endif void ssse3_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "mov $0xff, %%eax\n\t" - "movd %%eax, %%xmm0\n\t" - "pshufd $0x0, %%xmm0, %%xmm0\n\t" - "movdqa %4, %%xmm5\n\t" - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x4, %2\n\t" - "ssse3_delta8_rgba_iter:\n\t" - "movdqa (%0,%3,4), %%xmm1\n\t" - "movdqa (%1,%3,4), %%xmm2\n\t" - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm3\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x8, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "pslld $0x2, %%xmm2\n\t" - "paddd %%xmm1, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm1\n\t" - "pand %%xmm0, %%xmm1\n\t" - "paddd %%xmm1, %%xmm1\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x10, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "pshufb %%xmm5, %%xmm1\n\t" - "movd %%xmm1, %%eax\n\t" - "movnti %%eax, (%2,%3)\n\t" - "sub $0x4, %3\n\t" - "jnz ssse3_delta8_rgba_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (*movemask) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" - ); + + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "mov $0xff, %%eax\n\t" + "movd %%eax, %%xmm0\n\t" + "pshufd $0x0, %%xmm0, %%xmm0\n\t" + "movdqa %4, %%xmm5\n\t" + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x4, %2\n\t" + "ssse3_delta8_rgba_iter:\n\t" + "movdqa (%0,%3,4), %%xmm1\n\t" + "movdqa (%1,%3,4), %%xmm2\n\t" + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm3\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x8, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "pslld $0x2, %%xmm2\n\t" + "paddd %%xmm1, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm1\n\t" + "pand %%xmm0, %%xmm1\n\t" + "paddd %%xmm1, %%xmm1\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x10, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "pshufb %%xmm5, %%xmm1\n\t" + "movd %%xmm1, %%eax\n\t" + "movnti %%eax, (%2,%3)\n\t" + "sub $0x4, %3\n\t" + "jnz ssse3_delta8_rgba_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (*movemask) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -3789,52 +3789,52 @@ __attribute__((noinline,__target__("ssse3"))) #endif void ssse3_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "mov $0xff, %%eax\n\t" - "movd %%eax, %%xmm0\n\t" - "pshufd $0x0, %%xmm0, %%xmm0\n\t" - "movdqa %4, %%xmm5\n\t" - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x4, %2\n\t" - "ssse3_delta8_bgra_iter:\n\t" - "movdqa (%0,%3,4), %%xmm1\n\t" - "movdqa (%1,%3,4), %%xmm2\n\t" - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm3\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x8, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "pslld $0x2, %%xmm2\n\t" - "paddd %%xmm1, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm1\n\t" - "pand %%xmm0, %%xmm1\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x10, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "paddd %%xmm2, %%xmm2\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "pshufb %%xmm5, %%xmm1\n\t" - "movd %%xmm1, %%eax\n\t" - "movnti %%eax, (%2,%3)\n\t" - "sub $0x4, %3\n\t" - "jnz ssse3_delta8_bgra_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (*movemask) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" - ); + + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "mov $0xff, %%eax\n\t" + "movd %%eax, %%xmm0\n\t" + "pshufd $0x0, %%xmm0, %%xmm0\n\t" + "movdqa %4, %%xmm5\n\t" + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x4, %2\n\t" + "ssse3_delta8_bgra_iter:\n\t" + "movdqa (%0,%3,4), %%xmm1\n\t" + "movdqa (%1,%3,4), %%xmm2\n\t" + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm3\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x8, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "pslld $0x2, %%xmm2\n\t" + "paddd %%xmm1, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm1\n\t" + "pand %%xmm0, %%xmm1\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x10, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "paddd %%xmm2, %%xmm2\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "pshufb %%xmm5, %%xmm1\n\t" + "movd %%xmm1, %%eax\n\t" + "movnti %%eax, (%2,%3)\n\t" + "sub $0x4, %3\n\t" + "jnz ssse3_delta8_bgra_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (*movemask) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -3844,53 +3844,53 @@ __attribute__((noinline,__target__("ssse3"))) #endif void ssse3_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "mov $0xff, %%eax\n\t" - "movd %%eax, %%xmm0\n\t" - "pshufd $0x0, %%xmm0, %%xmm0\n\t" - "movdqa %4, %%xmm5\n\t" - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x4, %2\n\t" - "ssse3_delta8_argb_iter:\n\t" - "movdqa (%0,%3,4), %%xmm1\n\t" - "movdqa (%1,%3,4), %%xmm2\n\t" - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm3\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x10, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "pslld $0x2, %%xmm2\n\t" - "paddd %%xmm1, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm1\n\t" - "psrld $0x8, %%xmm1\n\t" - "pand %%xmm0, %%xmm1\n\t" - "paddd %%xmm1, %%xmm1\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x18, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "pshufb %%xmm5, %%xmm1\n\t" - "movd %%xmm1, %%eax\n\t" - "movnti %%eax, (%2,%3)\n\t" - "sub $0x4, %3\n\t" - "jnz ssse3_delta8_argb_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (*movemask) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" - ); + + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "mov $0xff, %%eax\n\t" + "movd %%eax, %%xmm0\n\t" + "pshufd $0x0, %%xmm0, %%xmm0\n\t" + "movdqa %4, %%xmm5\n\t" + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x4, %2\n\t" + "ssse3_delta8_argb_iter:\n\t" + "movdqa (%0,%3,4), %%xmm1\n\t" + "movdqa (%1,%3,4), %%xmm2\n\t" + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm3\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x10, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "pslld $0x2, %%xmm2\n\t" + "paddd %%xmm1, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm1\n\t" + "psrld $0x8, %%xmm1\n\t" + "pand %%xmm0, %%xmm1\n\t" + "paddd %%xmm1, %%xmm1\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x18, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "pshufb %%xmm5, %%xmm1\n\t" + "movd %%xmm1, %%eax\n\t" + "movnti %%eax, (%2,%3)\n\t" + "sub $0x4, %3\n\t" + "jnz ssse3_delta8_argb_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (*movemask) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -3900,53 +3900,53 @@ __attribute__((noinline,__target__("ssse3"))) #endif void ssse3_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "mov $0xff, %%eax\n\t" - "movd %%eax, %%xmm0\n\t" - "pshufd $0x0, %%xmm0, %%xmm0\n\t" - "movdqa %4, %%xmm5\n\t" - "sub $0x10, %0\n\t" - "sub $0x10, %1\n\t" - "sub $0x4, %2\n\t" - "ssse3_delta8_abgr_iter:\n\t" - "movdqa (%0,%3,4), %%xmm1\n\t" - "movdqa (%1,%3,4), %%xmm2\n\t" - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm3\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x10, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "pslld $0x2, %%xmm2\n\t" - "paddd %%xmm1, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm1\n\t" - "psrld $0x8, %%xmm1\n\t" - "pand %%xmm0, %%xmm1\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x18, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "paddd %%xmm2, %%xmm2\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "pshufb %%xmm5, %%xmm1\n\t" - "movd %%xmm1, %%eax\n\t" - "movnti %%eax, (%2,%3)\n\t" - "sub $0x4, %3\n\t" - "jnz ssse3_delta8_abgr_iter\n\t" - : - : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (*movemask) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" - ); + + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "mov $0xff, %%eax\n\t" + "movd %%eax, %%xmm0\n\t" + "pshufd $0x0, %%xmm0, %%xmm0\n\t" + "movdqa %4, %%xmm5\n\t" + "sub $0x10, %0\n\t" + "sub $0x10, %1\n\t" + "sub $0x4, %2\n\t" + "ssse3_delta8_abgr_iter:\n\t" + "movdqa (%0,%3,4), %%xmm1\n\t" + "movdqa (%1,%3,4), %%xmm2\n\t" + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm3\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x10, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "pslld $0x2, %%xmm2\n\t" + "paddd %%xmm1, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm1\n\t" + "psrld $0x8, %%xmm1\n\t" + "pand %%xmm0, %%xmm1\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x18, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "paddd %%xmm2, %%xmm2\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "pshufb %%xmm5, %%xmm1\n\t" + "movd %%xmm1, %%eax\n\t" + "movnti %%eax, (%2,%3)\n\t" + "sub $0x4, %3\n\t" + "jnz ssse3_delta8_abgr_iter\n\t" + : + : "r" (col1), "r" (col2), "r" (result), "r" (count), "m" (*movemask) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -3955,198 +3955,198 @@ void ssse3_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result /* RGB24 to grayscale */ __attribute__((noinline)) void std_convert_rgb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - r = col1[0]; - g = col1[1]; - b = col1[2]; - result[0] = (r + r + b + g + g + g + g + g)>>3; - r = col1[3]; - g = col1[4]; - b = col1[5]; - result[1] = (r + r + b + g + g + g + g + g)>>3; - r = col1[6]; - g = col1[7]; - b = col1[8]; - result[2] = (r + r + b + g + g + g + g + g)>>3; - r = col1[9]; - g = col1[10]; - b = col1[11]; - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 12; - result += 4; - } + unsigned int r,g,b; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + r = col1[0]; + g = col1[1]; + b = col1[2]; + result[0] = (r + r + b + g + g + g + g + g)>>3; + r = col1[3]; + g = col1[4]; + b = col1[5]; + result[1] = (r + r + b + g + g + g + g + g)>>3; + r = col1[6]; + g = col1[7]; + b = col1[8]; + result[2] = (r + r + b + g + g + g + g + g)>>3; + r = col1[9]; + g = col1[10]; + b = col1[11]; + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 12; + result += 4; + } } /* BGR24 to grayscale */ __attribute__((noinline)) void std_convert_bgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - b = col1[0]; - g = col1[1]; - r = col1[2]; - result[0] = (r + r + b + g + g + g + g + g)>>3; - b = col1[3]; - g = col1[4]; - r = col1[5]; - result[1] = (r + r + b + g + g + g + g + g)>>3; - b = col1[6]; - g = col1[7]; - r = col1[8]; - result[2] = (r + r + b + g + g + g + g + g)>>3; - b = col1[9]; - g = col1[10]; - r = col1[11]; - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 12; - result += 4; - } + unsigned int r,g,b; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + b = col1[0]; + g = col1[1]; + r = col1[2]; + result[0] = (r + r + b + g + g + g + g + g)>>3; + b = col1[3]; + g = col1[4]; + r = col1[5]; + result[1] = (r + r + b + g + g + g + g + g)>>3; + b = col1[6]; + g = col1[7]; + r = col1[8]; + result[2] = (r + r + b + g + g + g + g + g)>>3; + b = col1[9]; + g = col1[10]; + r = col1[11]; + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 12; + result += 4; + } } /* RGBA to grayscale */ __attribute__((noinline)) void std_convert_rgba_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - r = col1[0]; - g = col1[1]; - b = col1[2]; - result[0] = (r + r + b + g + g + g + g + g)>>3; - r = col1[4]; - g = col1[5]; - b = col1[6]; - result[1] = (r + r + b + g + g + g + g + g)>>3; - r = col1[8]; - g = col1[9]; - b = col1[10]; - result[2] = (r + r + b + g + g + g + g + g)>>3; - r = col1[12]; - g = col1[13]; - b = col1[14]; - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 16; - result += 4; - } + unsigned int r,g,b; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + r = col1[0]; + g = col1[1]; + b = col1[2]; + result[0] = (r + r + b + g + g + g + g + g)>>3; + r = col1[4]; + g = col1[5]; + b = col1[6]; + result[1] = (r + r + b + g + g + g + g + g)>>3; + r = col1[8]; + g = col1[9]; + b = col1[10]; + result[2] = (r + r + b + g + g + g + g + g)>>3; + r = col1[12]; + g = col1[13]; + b = col1[14]; + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 16; + result += 4; + } } /* BGRA to grayscale */ __attribute__((noinline)) void std_convert_bgra_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - b = col1[0]; - g = col1[1]; - r = col1[2]; - result[0] = (r + r + b + g + g + g + g + g)>>3; - b = col1[4]; - g = col1[5]; - r = col1[6]; - result[1] = (r + r + b + g + g + g + g + g)>>3; - b = col1[8]; - g = col1[9]; - r = col1[10]; - result[2] = (r + r + b + g + g + g + g + g)>>3; - b = col1[12]; - g = col1[13]; - r = col1[14]; - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 16; - result += 4; - } + unsigned int r,g,b; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + b = col1[0]; + g = col1[1]; + r = col1[2]; + result[0] = (r + r + b + g + g + g + g + g)>>3; + b = col1[4]; + g = col1[5]; + r = col1[6]; + result[1] = (r + r + b + g + g + g + g + g)>>3; + b = col1[8]; + g = col1[9]; + r = col1[10]; + result[2] = (r + r + b + g + g + g + g + g)>>3; + b = col1[12]; + g = col1[13]; + r = col1[14]; + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 16; + result += 4; + } } /* ARGB to grayscale */ __attribute__((noinline)) void std_convert_argb_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - r = col1[1]; - g = col1[2]; - b = col1[3]; - result[0] = (r + r + b + g + g + g + g + g)>>3; - r = col1[5]; - g = col1[6]; - b = col1[7]; - result[1] = (r + r + b + g + g + g + g + g)>>3; - r = col1[9]; - g = col1[10]; - b = col1[11]; - result[2] = (r + r + b + g + g + g + g + g)>>3; - r = col1[13]; - g = col1[14]; - b = col1[15]; - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 16; - result += 4; - } + unsigned int r,g,b; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + r = col1[1]; + g = col1[2]; + b = col1[3]; + result[0] = (r + r + b + g + g + g + g + g)>>3; + r = col1[5]; + g = col1[6]; + b = col1[7]; + result[1] = (r + r + b + g + g + g + g + g)>>3; + r = col1[9]; + g = col1[10]; + b = col1[11]; + result[2] = (r + r + b + g + g + g + g + g)>>3; + r = col1[13]; + g = col1[14]; + b = col1[15]; + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 16; + result += 4; + } } /* ABGR to grayscale */ __attribute__((noinline)) void std_convert_abgr_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - b = col1[1]; - g = col1[2]; - r = col1[3]; - result[0] = (r + r + b + g + g + g + g + g)>>3; - b = col1[5]; - g = col1[6]; - r = col1[7]; - result[1] = (r + r + b + g + g + g + g + g)>>3; - b = col1[9]; - g = col1[10]; - r = col1[11]; - result[2] = (r + r + b + g + g + g + g + g)>>3; - b = col1[13]; - g = col1[14]; - r = col1[15]; - result[3] = (r + r + b + g + g + g + g + g)>>3; - - col1 += 16; - result += 4; - } + unsigned int r,g,b; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + b = col1[1]; + g = col1[2]; + r = col1[3]; + result[0] = (r + r + b + g + g + g + g + g)>>3; + b = col1[5]; + g = col1[6]; + r = col1[7]; + result[1] = (r + r + b + g + g + g + g + g)>>3; + b = col1[9]; + g = col1[10]; + r = col1[11]; + result[2] = (r + r + b + g + g + g + g + g)>>3; + b = col1[13]; + g = col1[14]; + r = col1[15]; + result[3] = (r + r + b + g + g + g + g + g)>>3; + + col1 += 16; + result += 4; + } } /* Converts a YUYV image into grayscale by extracting the Y channel */ __attribute__((noinline)) void std_convert_yuyv_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) { - const uint16_t* yuvbuf = (const uint16_t*)col1; - const uint8_t* const max_ptr = result + count; - - while(result < max_ptr) { - result[0] = (uint8_t)yuvbuf[0]; - result[1] = (uint8_t)yuvbuf[1]; - result[2] = (uint8_t)yuvbuf[2]; - result[3] = (uint8_t)yuvbuf[3]; - result[4] = (uint8_t)yuvbuf[4]; - result[5] = (uint8_t)yuvbuf[5]; - result[6] = (uint8_t)yuvbuf[6]; - result[7] = (uint8_t)yuvbuf[7]; - result[8] = (uint8_t)yuvbuf[8]; - result[9] = (uint8_t)yuvbuf[9]; - result[10] = (uint8_t)yuvbuf[10]; - result[11] = (uint8_t)yuvbuf[11]; - result[12] = (uint8_t)yuvbuf[12]; - result[13] = (uint8_t)yuvbuf[13]; - result[14] = (uint8_t)yuvbuf[14]; - result[15] = (uint8_t)yuvbuf[15]; - - yuvbuf += 16; - result += 16; - } + const uint16_t* yuvbuf = (const uint16_t*)col1; + const uint8_t* const max_ptr = result + count; + + while(result < max_ptr) { + result[0] = (uint8_t)yuvbuf[0]; + result[1] = (uint8_t)yuvbuf[1]; + result[2] = (uint8_t)yuvbuf[2]; + result[3] = (uint8_t)yuvbuf[3]; + result[4] = (uint8_t)yuvbuf[4]; + result[5] = (uint8_t)yuvbuf[5]; + result[6] = (uint8_t)yuvbuf[6]; + result[7] = (uint8_t)yuvbuf[7]; + result[8] = (uint8_t)yuvbuf[8]; + result[9] = (uint8_t)yuvbuf[9]; + result[10] = (uint8_t)yuvbuf[10]; + result[11] = (uint8_t)yuvbuf[11]; + result[12] = (uint8_t)yuvbuf[12]; + result[13] = (uint8_t)yuvbuf[13]; + result[14] = (uint8_t)yuvbuf[14]; + result[15] = (uint8_t)yuvbuf[15]; + + yuvbuf += 16; + result += 16; + } } /* RGBA to grayscale SSSE3 */ @@ -4156,45 +4156,45 @@ __attribute__((noinline,__target__("ssse3"))) void ssse3_convert_rgba_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "mov $0xff, %%eax\n\t" - "movd %%eax, %%xmm0\n\t" - "pshufd $0x0, %%xmm0, %%xmm0\n\t" - "movdqa %3, %%xmm5\n\t" - "sub $0x10, %0\n\t" - "sub $0x4, %1\n\t" - "ssse3_convert_rgba_gray8_iter:\n\t" - "movdqa (%0,%2,4), %%xmm3\n\t" - "psrlq $0x3, %%xmm3\n\t" - "pand %%xmm4, %%xmm3\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x8, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "pslld $0x2, %%xmm2\n\t" - "paddd %%xmm1, %%xmm2\n\t" - "movdqa %%xmm3, %%xmm1\n\t" - "pand %%xmm0, %%xmm1\n\t" - "paddd %%xmm1, %%xmm1\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "movdqa %%xmm3, %%xmm2\n\t" - "psrld $0x10, %%xmm2\n\t" - "pand %%xmm0, %%xmm2\n\t" - "paddd %%xmm2, %%xmm1\n\t" - "pshufb %%xmm5, %%xmm1\n\t" - "movd %%xmm1, %%eax\n\t" - "movnti %%eax, (%1,%2)\n\t" - "sub $0x4, %2\n\t" - "jnz ssse3_convert_rgba_gray8_iter\n\t" - : - : "r" (col1), "r" (result), "r" (count), "m" (*movemask) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" - ); + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "mov $0xff, %%eax\n\t" + "movd %%eax, %%xmm0\n\t" + "pshufd $0x0, %%xmm0, %%xmm0\n\t" + "movdqa %3, %%xmm5\n\t" + "sub $0x10, %0\n\t" + "sub $0x4, %1\n\t" + "ssse3_convert_rgba_gray8_iter:\n\t" + "movdqa (%0,%2,4), %%xmm3\n\t" + "psrlq $0x3, %%xmm3\n\t" + "pand %%xmm4, %%xmm3\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x8, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "pslld $0x2, %%xmm2\n\t" + "paddd %%xmm1, %%xmm2\n\t" + "movdqa %%xmm3, %%xmm1\n\t" + "pand %%xmm0, %%xmm1\n\t" + "paddd %%xmm1, %%xmm1\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "movdqa %%xmm3, %%xmm2\n\t" + "psrld $0x10, %%xmm2\n\t" + "pand %%xmm0, %%xmm2\n\t" + "paddd %%xmm2, %%xmm1\n\t" + "pshufb %%xmm5, %%xmm1\n\t" + "movd %%xmm1, %%eax\n\t" + "movnti %%eax, (%1,%2)\n\t" + "sub $0x4, %2\n\t" + "jnz ssse3_convert_rgba_gray8_iter\n\t" + : + : "r" (col1), "r" (result), "r" (count), "m" (*movemask) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -4204,156 +4204,156 @@ __attribute__((noinline,__target__("ssse3"))) #endif void ssse3_convert_yuyv_gray8(const uint8_t* col1, uint8_t* result, unsigned long count) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - unsigned long i = 0; + unsigned long i = 0; - __attribute__((aligned(16))) static const uint8_t movemask1[16] = {0,2,4,6,8,10,12,14,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; - __attribute__((aligned(16))) static const uint8_t movemask2[16] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0,2,4,6,8,10,12,14}; - - /* XMM0 - General purpose */ - /* XMM1 - General purpose */ - /* XMM2 - unused */ - /* XMM3 - shift mask 1 */ - /* XMM4 - shift mask 2 */ - /* XMM5 - unused*/ - /* XMM6 - unused */ - /* XMM7 - unused */ + __attribute__((aligned(16))) static const uint8_t movemask1[16] = {0,2,4,6,8,10,12,14,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; + __attribute__((aligned(16))) static const uint8_t movemask2[16] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0,2,4,6,8,10,12,14}; + + /* XMM0 - General purpose */ + /* XMM1 - General purpose */ + /* XMM2 - unused */ + /* XMM3 - shift mask 1 */ + /* XMM4 - shift mask 2 */ + /* XMM5 - unused*/ + /* XMM6 - unused */ + /* XMM7 - unused */ - __asm__ __volatile__ ( - "movdqa %4, %%xmm3\n\t" - "movdqa %5, %%xmm4\n\t" - "algo_ssse3_convert_yuyv_gray8:\n\t" - "movdqa (%0), %%xmm0\n\t" - "pshufb %%xmm3, %%xmm0\n\t" - "movdqa 0x10(%0), %%xmm1\n\t" - "pshufb %%xmm4, %%xmm1\n\t" - "por %%xmm1, %%xmm0\n\t" - "movntdq %%xmm0, (%1)\n\t" - "add $0x10, %3\n\t" - "add $0x10, %1\n\t" - "add $0x20, %0\n\t" - "cmp %2, %3\n\t" - "jb algo_ssse3_convert_yuyv_gray8\n\t" - : + __asm__ __volatile__ ( + "movdqa %4, %%xmm3\n\t" + "movdqa %5, %%xmm4\n\t" + "algo_ssse3_convert_yuyv_gray8:\n\t" + "movdqa (%0), %%xmm0\n\t" + "pshufb %%xmm3, %%xmm0\n\t" + "movdqa 0x10(%0), %%xmm1\n\t" + "pshufb %%xmm4, %%xmm1\n\t" + "por %%xmm1, %%xmm0\n\t" + "movntdq %%xmm0, (%1)\n\t" + "add $0x10, %3\n\t" + "add $0x10, %1\n\t" + "add $0x20, %0\n\t" + "cmp %2, %3\n\t" + "jb algo_ssse3_convert_yuyv_gray8\n\t" + : #if (defined(_DEBUG) && !defined(__x86_64__)) /* Use one less register to allow compilation to success on 32bit with omit frame pointer disabled */ - : "r" (col1), "r" (result), "m" (count), "r" (i), "m" (*movemask1), "m" (*movemask2) + : "r" (col1), "r" (result), "m" (count), "r" (i), "m" (*movemask1), "m" (*movemask2) #else - : "r" (col1), "r" (result), "r" (count), "r" (i), "m" (*movemask1), "m" (*movemask2) + : "r" (col1), "r" (result), "r" (count), "r" (i), "m" (*movemask1), "m" (*movemask2) #endif - : "%xmm3", "%xmm4", "cc", "memory" - ); + : "%xmm3", "%xmm4", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } /* YUYV to RGB24 - relocated from zm_local_camera.cpp */ __attribute__((noinline)) void zm_convert_yuyv_rgb(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - unsigned int y1,y2,u,v; - for(unsigned int i=0; i < count; i += 2, col1 += 4, result += 6) { - y1 = col1[0]; - u = col1[1]; - y2 = col1[2]; - v = col1[3]; + unsigned int r,g,b; + unsigned int y1,y2,u,v; + for(unsigned int i=0; i < count; i += 2, col1 += 4, result += 6) { + y1 = col1[0]; + u = col1[1]; + y2 = col1[2]; + v = col1[3]; - r = y1 + r_v_table[v]; - g = y1 - (g_u_table[u]+g_v_table[v]); - b = y1 + b_u_table[u]; - - result[0] = r<0?0:(r>255?255:r); - result[1] = g<0?0:(g>255?255:g); - result[2] = b<0?0:(b>255?255:b); - - r = y2 + r_v_table[v]; - g = y2 - (g_u_table[u]+g_v_table[v]); - b = y2 + b_u_table[u]; + r = y1 + r_v_table[v]; + g = y1 - (g_u_table[u]+g_v_table[v]); + b = y1 + b_u_table[u]; + + result[0] = r<0?0:(r>255?255:r); + result[1] = g<0?0:(g>255?255:g); + result[2] = b<0?0:(b>255?255:b); + + r = y2 + r_v_table[v]; + g = y2 - (g_u_table[u]+g_v_table[v]); + b = y2 + b_u_table[u]; - result[3] = r<0?0:(r>255?255:r); - result[4] = g<0?0:(g>255?255:g); - result[5] = b<0?0:(b>255?255:b); - } - + result[3] = r<0?0:(r>255?255:r); + result[4] = g<0?0:(g>255?255:g); + result[5] = b<0?0:(b>255?255:b); + } + } /* YUYV to RGBA - modified the one above */ __attribute__((noinline)) void zm_convert_yuyv_rgba(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - unsigned int y1,y2,u,v; - for(unsigned int i=0; i < count; i += 2, col1 += 4, result += 8) { - y1 = col1[0]; - u = col1[1]; - y2 = col1[2]; - v = col1[3]; + unsigned int r,g,b; + unsigned int y1,y2,u,v; + for(unsigned int i=0; i < count; i += 2, col1 += 4, result += 8) { + y1 = col1[0]; + u = col1[1]; + y2 = col1[2]; + v = col1[3]; - r = y1 + r_v_table[v]; - g = y1 - (g_u_table[u]+g_v_table[v]); - b = y1 + b_u_table[u]; - - result[0] = r<0?0:(r>255?255:r); - result[1] = g<0?0:(g>255?255:g); - result[2] = b<0?0:(b>255?255:b); - - r = y2 + r_v_table[v]; - g = y2 - (g_u_table[u]+g_v_table[v]); - b = y2 + b_u_table[u]; + r = y1 + r_v_table[v]; + g = y1 - (g_u_table[u]+g_v_table[v]); + b = y1 + b_u_table[u]; + + result[0] = r<0?0:(r>255?255:r); + result[1] = g<0?0:(g>255?255:g); + result[2] = b<0?0:(b>255?255:b); + + r = y2 + r_v_table[v]; + g = y2 - (g_u_table[u]+g_v_table[v]); + b = y2 + b_u_table[u]; - result[4] = r<0?0:(r>255?255:r); - result[5] = g<0?0:(g>255?255:g); - result[6] = b<0?0:(b>255?255:b); - } - + result[4] = r<0?0:(r>255?255:r); + result[5] = g<0?0:(g>255?255:g); + result[6] = b<0?0:(b>255?255:b); + } + } /* RGB555 to RGB24 - relocated from zm_local_camera.cpp */ __attribute__((noinline)) void zm_convert_rgb555_rgb(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - for(unsigned int i=0; i < count; i++, col1 += 2, result += 3) { - b = ((*col1)<<3)&0xf8; - g = (((*(col1+1))<<6)|((*col1)>>2))&0xf8; - r = ((*(col1+1))<<1)&0xf8; - result[0] = r; - result[1] = g; - result[2] = b; - } + unsigned int r,g,b; + for(unsigned int i=0; i < count; i++, col1 += 2, result += 3) { + b = ((*col1)<<3)&0xf8; + g = (((*(col1+1))<<6)|((*col1)>>2))&0xf8; + r = ((*(col1+1))<<1)&0xf8; + result[0] = r; + result[1] = g; + result[2] = b; + } } /* RGB555 to RGBA - modified the one above */ __attribute__((noinline)) void zm_convert_rgb555_rgba(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - for(unsigned int i=0; i < count; i++, col1 += 2, result += 4) { - b = ((*col1)<<3)&0xf8; - g = (((*(col1+1))<<6)|((*col1)>>2))&0xf8; - r = ((*(col1+1))<<1)&0xf8; - result[0] = r; - result[1] = g; - result[2] = b; - } + unsigned int r,g,b; + for(unsigned int i=0; i < count; i++, col1 += 2, result += 4) { + b = ((*col1)<<3)&0xf8; + g = (((*(col1+1))<<6)|((*col1)>>2))&0xf8; + r = ((*(col1+1))<<1)&0xf8; + result[0] = r; + result[1] = g; + result[2] = b; + } } /* RGB565 to RGB24 - relocated from zm_local_camera.cpp */ __attribute__((noinline)) void zm_convert_rgb565_rgb(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - for(unsigned int i=0; i < count; i++, col1 += 2, result += 3) { - b = ((*col1)<<3)&0xf8; - g = (((*(col1+1))<<5)|((*col1)>>3))&0xfc; - r = (*(col1+1))&0xf8; - result[0] = r; - result[1] = g; - result[2] = b; - } + unsigned int r,g,b; + for(unsigned int i=0; i < count; i++, col1 += 2, result += 3) { + b = ((*col1)<<3)&0xf8; + g = (((*(col1+1))<<5)|((*col1)>>3))&0xfc; + r = (*(col1+1))&0xf8; + result[0] = r; + result[1] = g; + result[2] = b; + } } /* RGB565 to RGBA - modified the one above */ __attribute__((noinline)) void zm_convert_rgb565_rgba(const uint8_t* col1, uint8_t* result, unsigned long count) { - unsigned int r,g,b; - for(unsigned int i=0; i < count; i++, col1 += 2, result += 4) { - b = ((*col1)<<3)&0xf8; - g = (((*(col1+1))<<5)|((*col1)>>3))&0xfc; - r = (*(col1+1))&0xf8; - result[0] = r; - result[1] = g; - result[2] = b; - } + unsigned int r,g,b; + for(unsigned int i=0; i < count; i++, col1 += 2, result += 4) { + b = ((*col1)<<3)&0xf8; + g = (((*(col1+1))<<5)|((*col1)>>3))&0xfc; + r = (*(col1+1))&0xf8; + result[0] = r; + result[1] = g; + result[2] = b; + } } /************************************************* DEINTERLACE FUNCTIONS *************************************************/ @@ -4361,461 +4361,461 @@ __attribute__((noinline)) void zm_convert_rgb565_rgba(const uint8_t* col1, uint8 /* Grayscale */ __attribute__((noinline)) void std_deinterlace_4field_gray8(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { - uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; - const uint8_t* const max_ptr = col1 + (width*(height-1)); - const uint8_t *max_ptr2; + uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; + const uint8_t* const max_ptr = col1 + (width*(height-1)); + const uint8_t *max_ptr2; - pcurrent = col1 + width; - pncurrent = col2 + width; - pabove = col1; - pnabove = col2; - pbelow = col1 + (width*2); - while(pcurrent < max_ptr) - { - max_ptr2 = pcurrent + width; - while(pcurrent < max_ptr2) { - if((unsigned int)((abs(*pnabove - *pabove) + abs(*pncurrent - *pcurrent)) >> 1) >= threshold) { - *pcurrent = (*pabove + *pbelow) >> 1; - } - pabove++; - pnabove++; - pcurrent++; - pncurrent++; - pbelow++; - } - pcurrent += width; - pncurrent += width; - pabove += width; - pnabove += width; - pbelow += width; - - } - - /* Special case for the last line */ - max_ptr2 = pcurrent + width; - while(pcurrent < max_ptr2) { - if((unsigned int)((abs(*pnabove - *pabove) + abs(*pncurrent - *pcurrent)) >> 1) >= threshold) { - *pcurrent = *pabove; - } - pabove++; - pnabove++; - pcurrent++; - pncurrent++; - } + pcurrent = col1 + width; + pncurrent = col2 + width; + pabove = col1; + pnabove = col2; + pbelow = col1 + (width*2); + while(pcurrent < max_ptr) + { + max_ptr2 = pcurrent + width; + while(pcurrent < max_ptr2) { + if((unsigned int)((abs(*pnabove - *pabove) + abs(*pncurrent - *pcurrent)) >> 1) >= threshold) { + *pcurrent = (*pabove + *pbelow) >> 1; + } + pabove++; + pnabove++; + pcurrent++; + pncurrent++; + pbelow++; + } + pcurrent += width; + pncurrent += width; + pabove += width; + pnabove += width; + pbelow += width; + + } + + /* Special case for the last line */ + max_ptr2 = pcurrent + width; + while(pcurrent < max_ptr2) { + if((unsigned int)((abs(*pnabove - *pabove) + abs(*pncurrent - *pcurrent)) >> 1) >= threshold) { + *pcurrent = *pabove; + } + pabove++; + pnabove++; + pcurrent++; + pncurrent++; + } } /* RGB */ __attribute__((noinline)) void std_deinterlace_4field_rgb(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { - uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; - const unsigned int row_width = width*3; - const uint8_t* const max_ptr = col1 + (row_width * (height-1)); - const uint8_t *max_ptr2; - unsigned int b, g, r; - unsigned int delta1, delta2; + uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; + const unsigned int row_width = width*3; + const uint8_t* const max_ptr = col1 + (row_width * (height-1)); + const uint8_t *max_ptr2; + unsigned int b, g, r; + unsigned int delta1, delta2; - pcurrent = col1 + (width*3); - pncurrent = col2 + (width*3); - pabove = col1; - pnabove = col2; - pbelow = col1 + ((width*2)*3); - while(pcurrent < max_ptr) - { - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - r = abs(pnabove[0] - pabove[0]); - g = abs(pnabove[1] - pabove[1]); - b = abs(pnabove[2] - pabove[2]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - r = abs(pncurrent[0] - pcurrent[0]); - g = abs(pncurrent[1] - pcurrent[1]); - b = abs(pncurrent[2] - pcurrent[2]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[0] = (pabove[0] + pbelow[0]) >> 1; - pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; - pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; - } - pabove += 3; - pnabove += 3; - pcurrent += 3; - pncurrent += 3; - pbelow += 3; - } - pcurrent += row_width; - pncurrent += row_width; - pabove += row_width; - pnabove += row_width; - pbelow += row_width; - - } - - /* Special case for the last line */ - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - r = abs(pnabove[0] - pabove[0]); - g = abs(pnabove[1] - pabove[1]); - b = abs(pnabove[2] - pabove[2]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - r = abs(pncurrent[0] - pcurrent[0]); - g = abs(pncurrent[1] - pcurrent[1]); - b = abs(pncurrent[2] - pcurrent[2]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[0] = pabove[0]; - pcurrent[1] = pabove[1]; - pcurrent[2] = pabove[2]; - } - pabove += 3; - pnabove += 3; - pcurrent += 3; - pncurrent += 3; - } + pcurrent = col1 + (width*3); + pncurrent = col2 + (width*3); + pabove = col1; + pnabove = col2; + pbelow = col1 + ((width*2)*3); + while(pcurrent < max_ptr) + { + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + r = abs(pnabove[0] - pabove[0]); + g = abs(pnabove[1] - pabove[1]); + b = abs(pnabove[2] - pabove[2]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + r = abs(pncurrent[0] - pcurrent[0]); + g = abs(pncurrent[1] - pcurrent[1]); + b = abs(pncurrent[2] - pcurrent[2]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[0] = (pabove[0] + pbelow[0]) >> 1; + pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; + pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; + } + pabove += 3; + pnabove += 3; + pcurrent += 3; + pncurrent += 3; + pbelow += 3; + } + pcurrent += row_width; + pncurrent += row_width; + pabove += row_width; + pnabove += row_width; + pbelow += row_width; + + } + + /* Special case for the last line */ + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + r = abs(pnabove[0] - pabove[0]); + g = abs(pnabove[1] - pabove[1]); + b = abs(pnabove[2] - pabove[2]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + r = abs(pncurrent[0] - pcurrent[0]); + g = abs(pncurrent[1] - pcurrent[1]); + b = abs(pncurrent[2] - pcurrent[2]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[0] = pabove[0]; + pcurrent[1] = pabove[1]; + pcurrent[2] = pabove[2]; + } + pabove += 3; + pnabove += 3; + pcurrent += 3; + pncurrent += 3; + } } /* BGR */ __attribute__((noinline)) void std_deinterlace_4field_bgr(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { - uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; - const unsigned int row_width = width*3; - const uint8_t* const max_ptr = col1 + (row_width * (height-1)); - const uint8_t *max_ptr2; - unsigned int b, g, r; - unsigned int delta1, delta2; + uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; + const unsigned int row_width = width*3; + const uint8_t* const max_ptr = col1 + (row_width * (height-1)); + const uint8_t *max_ptr2; + unsigned int b, g, r; + unsigned int delta1, delta2; - pcurrent = col1 + (width*3); - pncurrent = col2 + (width*3); - pabove = col1; - pnabove = col2; - pbelow = col1 + ((width*2)*3); - while(pcurrent < max_ptr) - { - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - b = abs(pnabove[0] - pabove[0]); - g = abs(pnabove[1] - pabove[1]); - r = abs(pnabove[2] - pabove[2]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - b = abs(pncurrent[0] - pcurrent[0]); - g = abs(pncurrent[1] - pcurrent[1]); - r = abs(pncurrent[2] - pcurrent[2]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[0] = (pabove[0] + pbelow[0]) >> 1; - pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; - pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; - } - pabove += 3; - pnabove += 3; - pcurrent += 3; - pncurrent += 3; - pbelow += 3; - } - pcurrent += row_width; - pncurrent += row_width; - pabove += row_width; - pnabove += row_width; - pbelow += row_width; - - } - - /* Special case for the last line */ - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - b = abs(pnabove[0] - pabove[0]); - g = abs(pnabove[1] - pabove[1]); - r = abs(pnabove[2] - pabove[2]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - b = abs(pncurrent[0] - pcurrent[0]); - g = abs(pncurrent[1] - pcurrent[1]); - r = abs(pncurrent[2] - pcurrent[2]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[0] = pabove[0]; - pcurrent[1] = pabove[1]; - pcurrent[2] = pabove[2]; - } - pabove += 3; - pnabove += 3; - pcurrent += 3; - pncurrent += 3; - } + pcurrent = col1 + (width*3); + pncurrent = col2 + (width*3); + pabove = col1; + pnabove = col2; + pbelow = col1 + ((width*2)*3); + while(pcurrent < max_ptr) + { + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + b = abs(pnabove[0] - pabove[0]); + g = abs(pnabove[1] - pabove[1]); + r = abs(pnabove[2] - pabove[2]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + b = abs(pncurrent[0] - pcurrent[0]); + g = abs(pncurrent[1] - pcurrent[1]); + r = abs(pncurrent[2] - pcurrent[2]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[0] = (pabove[0] + pbelow[0]) >> 1; + pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; + pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; + } + pabove += 3; + pnabove += 3; + pcurrent += 3; + pncurrent += 3; + pbelow += 3; + } + pcurrent += row_width; + pncurrent += row_width; + pabove += row_width; + pnabove += row_width; + pbelow += row_width; + + } + + /* Special case for the last line */ + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + b = abs(pnabove[0] - pabove[0]); + g = abs(pnabove[1] - pabove[1]); + r = abs(pnabove[2] - pabove[2]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + b = abs(pncurrent[0] - pcurrent[0]); + g = abs(pncurrent[1] - pcurrent[1]); + r = abs(pncurrent[2] - pcurrent[2]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[0] = pabove[0]; + pcurrent[1] = pabove[1]; + pcurrent[2] = pabove[2]; + } + pabove += 3; + pnabove += 3; + pcurrent += 3; + pncurrent += 3; + } } /* RGBA */ __attribute__((noinline)) void std_deinterlace_4field_rgba(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { - uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; - const unsigned int row_width = width*4; - const uint8_t* const max_ptr = col1 + (row_width * (height-1)); - const uint8_t *max_ptr2; - unsigned int b, g, r; - unsigned int delta1, delta2; + uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; + const unsigned int row_width = width*4; + const uint8_t* const max_ptr = col1 + (row_width * (height-1)); + const uint8_t *max_ptr2; + unsigned int b, g, r; + unsigned int delta1, delta2; - pcurrent = col1 + row_width; - pncurrent = col2 + row_width; - pabove = col1; - pnabove = col2; - pbelow = col1 + (row_width*2); - while(pcurrent < max_ptr) - { - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - r = abs(pnabove[0] - pabove[0]); - g = abs(pnabove[1] - pabove[1]); - b = abs(pnabove[2] - pabove[2]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - r = abs(pncurrent[0] - pcurrent[0]); - g = abs(pncurrent[1] - pcurrent[1]); - b = abs(pncurrent[2] - pcurrent[2]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[0] = (pabove[0] + pbelow[0]) >> 1; - pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; - pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; - } - pabove += 4; - pnabove += 4; - pcurrent += 4; - pncurrent += 4; - pbelow += 4; - } - pcurrent += row_width; - pncurrent += row_width; - pabove += row_width; - pnabove += row_width; - pbelow += row_width; - - } - - /* Special case for the last line */ - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - r = abs(pnabove[0] - pabove[0]); - g = abs(pnabove[1] - pabove[1]); - b = abs(pnabove[2] - pabove[2]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - r = abs(pncurrent[0] - pcurrent[0]); - g = abs(pncurrent[1] - pcurrent[1]); - b = abs(pncurrent[2] - pcurrent[2]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[0] = pabove[0]; - pcurrent[1] = pabove[1]; - pcurrent[2] = pabove[2]; - } - pabove += 4; - pnabove += 4; - pcurrent += 4; - pncurrent += 4; - } + pcurrent = col1 + row_width; + pncurrent = col2 + row_width; + pabove = col1; + pnabove = col2; + pbelow = col1 + (row_width*2); + while(pcurrent < max_ptr) + { + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + r = abs(pnabove[0] - pabove[0]); + g = abs(pnabove[1] - pabove[1]); + b = abs(pnabove[2] - pabove[2]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + r = abs(pncurrent[0] - pcurrent[0]); + g = abs(pncurrent[1] - pcurrent[1]); + b = abs(pncurrent[2] - pcurrent[2]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[0] = (pabove[0] + pbelow[0]) >> 1; + pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; + pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; + } + pabove += 4; + pnabove += 4; + pcurrent += 4; + pncurrent += 4; + pbelow += 4; + } + pcurrent += row_width; + pncurrent += row_width; + pabove += row_width; + pnabove += row_width; + pbelow += row_width; + + } + + /* Special case for the last line */ + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + r = abs(pnabove[0] - pabove[0]); + g = abs(pnabove[1] - pabove[1]); + b = abs(pnabove[2] - pabove[2]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + r = abs(pncurrent[0] - pcurrent[0]); + g = abs(pncurrent[1] - pcurrent[1]); + b = abs(pncurrent[2] - pcurrent[2]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[0] = pabove[0]; + pcurrent[1] = pabove[1]; + pcurrent[2] = pabove[2]; + } + pabove += 4; + pnabove += 4; + pcurrent += 4; + pncurrent += 4; + } } /* BGRA */ __attribute__((noinline)) void std_deinterlace_4field_bgra(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { - uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; - const unsigned int row_width = width*4; - const uint8_t* const max_ptr = col1 + (row_width * (height-1)); - const uint8_t *max_ptr2; - unsigned int b, g, r; - unsigned int delta1, delta2; + uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; + const unsigned int row_width = width*4; + const uint8_t* const max_ptr = col1 + (row_width * (height-1)); + const uint8_t *max_ptr2; + unsigned int b, g, r; + unsigned int delta1, delta2; - pcurrent = col1 + row_width; - pncurrent = col2 + row_width; - pabove = col1; - pnabove = col2; - pbelow = col1 + (row_width*2); - while(pcurrent < max_ptr) - { - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - b = abs(pnabove[0] - pabove[0]); - g = abs(pnabove[1] - pabove[1]); - r = abs(pnabove[2] - pabove[2]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - b = abs(pncurrent[0] - pcurrent[0]); - g = abs(pncurrent[1] - pcurrent[1]); - r = abs(pncurrent[2] - pcurrent[2]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[0] = (pabove[0] + pbelow[0]) >> 1; - pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; - pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; - } - pabove += 4; - pnabove += 4; - pcurrent += 4; - pncurrent += 4; - pbelow += 4; - } - pcurrent += row_width; - pncurrent += row_width; - pabove += row_width; - pnabove += row_width; - pbelow += row_width; - - } - - /* Special case for the last line */ - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - b = abs(pnabove[0] - pabove[0]); - g = abs(pnabove[1] - pabove[1]); - r = abs(pnabove[2] - pabove[2]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - b = abs(pncurrent[0] - pcurrent[0]); - g = abs(pncurrent[1] - pcurrent[1]); - r = abs(pncurrent[2] - pcurrent[2]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[0] = pabove[0]; - pcurrent[1] = pabove[1]; - pcurrent[2] = pabove[2]; - } - pabove += 4; - pnabove += 4; - pcurrent += 4; - pncurrent += 4; - } + pcurrent = col1 + row_width; + pncurrent = col2 + row_width; + pabove = col1; + pnabove = col2; + pbelow = col1 + (row_width*2); + while(pcurrent < max_ptr) + { + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + b = abs(pnabove[0] - pabove[0]); + g = abs(pnabove[1] - pabove[1]); + r = abs(pnabove[2] - pabove[2]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + b = abs(pncurrent[0] - pcurrent[0]); + g = abs(pncurrent[1] - pcurrent[1]); + r = abs(pncurrent[2] - pcurrent[2]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[0] = (pabove[0] + pbelow[0]) >> 1; + pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; + pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; + } + pabove += 4; + pnabove += 4; + pcurrent += 4; + pncurrent += 4; + pbelow += 4; + } + pcurrent += row_width; + pncurrent += row_width; + pabove += row_width; + pnabove += row_width; + pbelow += row_width; + + } + + /* Special case for the last line */ + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + b = abs(pnabove[0] - pabove[0]); + g = abs(pnabove[1] - pabove[1]); + r = abs(pnabove[2] - pabove[2]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + b = abs(pncurrent[0] - pcurrent[0]); + g = abs(pncurrent[1] - pcurrent[1]); + r = abs(pncurrent[2] - pcurrent[2]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[0] = pabove[0]; + pcurrent[1] = pabove[1]; + pcurrent[2] = pabove[2]; + } + pabove += 4; + pnabove += 4; + pcurrent += 4; + pncurrent += 4; + } } /* ARGB */ __attribute__((noinline)) void std_deinterlace_4field_argb(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { - uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; - const unsigned int row_width = width*4; - const uint8_t* const max_ptr = col1 + (row_width * (height-1)); - const uint8_t *max_ptr2; - unsigned int b, g, r; - unsigned int delta1, delta2; + uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; + const unsigned int row_width = width*4; + const uint8_t* const max_ptr = col1 + (row_width * (height-1)); + const uint8_t *max_ptr2; + unsigned int b, g, r; + unsigned int delta1, delta2; - pcurrent = col1 + row_width; - pncurrent = col2 + row_width; - pabove = col1; - pnabove = col2; - pbelow = col1 + (row_width*2); - while(pcurrent < max_ptr) - { - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - r = abs(pnabove[1] - pabove[1]); - g = abs(pnabove[2] - pabove[2]); - b = abs(pnabove[3] - pabove[3]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - r = abs(pncurrent[1] - pcurrent[1]); - g = abs(pncurrent[2] - pcurrent[2]); - b = abs(pncurrent[3] - pcurrent[3]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; - pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; - pcurrent[3] = (pabove[3] + pbelow[3]) >> 1; - } - pabove += 4; - pnabove += 4; - pcurrent += 4; - pncurrent += 4; - pbelow += 4; - } - pcurrent += row_width; - pncurrent += row_width; - pabove += row_width; - pnabove += row_width; - pbelow += row_width; - - } - - /* Special case for the last line */ - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - r = abs(pnabove[1] - pabove[1]); - g = abs(pnabove[2] - pabove[2]); - b = abs(pnabove[3] - pabove[3]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - r = abs(pncurrent[1] - pcurrent[1]); - g = abs(pncurrent[2] - pcurrent[2]); - b = abs(pncurrent[3] - pcurrent[3]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[1] = pabove[1]; - pcurrent[2] = pabove[2]; - pcurrent[3] = pabove[3]; - } - pabove += 4; - pnabove += 4; - pcurrent += 4; - pncurrent += 4; - } + pcurrent = col1 + row_width; + pncurrent = col2 + row_width; + pabove = col1; + pnabove = col2; + pbelow = col1 + (row_width*2); + while(pcurrent < max_ptr) + { + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + r = abs(pnabove[1] - pabove[1]); + g = abs(pnabove[2] - pabove[2]); + b = abs(pnabove[3] - pabove[3]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + r = abs(pncurrent[1] - pcurrent[1]); + g = abs(pncurrent[2] - pcurrent[2]); + b = abs(pncurrent[3] - pcurrent[3]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; + pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; + pcurrent[3] = (pabove[3] + pbelow[3]) >> 1; + } + pabove += 4; + pnabove += 4; + pcurrent += 4; + pncurrent += 4; + pbelow += 4; + } + pcurrent += row_width; + pncurrent += row_width; + pabove += row_width; + pnabove += row_width; + pbelow += row_width; + + } + + /* Special case for the last line */ + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + r = abs(pnabove[1] - pabove[1]); + g = abs(pnabove[2] - pabove[2]); + b = abs(pnabove[3] - pabove[3]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + r = abs(pncurrent[1] - pcurrent[1]); + g = abs(pncurrent[2] - pcurrent[2]); + b = abs(pncurrent[3] - pcurrent[3]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[1] = pabove[1]; + pcurrent[2] = pabove[2]; + pcurrent[3] = pabove[3]; + } + pabove += 4; + pnabove += 4; + pcurrent += 4; + pncurrent += 4; + } } /* ABGR */ __attribute__((noinline)) void std_deinterlace_4field_abgr(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { - uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; - const unsigned int row_width = width*4; - const uint8_t* const max_ptr = col1 + (row_width * (height-1)); - const uint8_t *max_ptr2; - unsigned int b, g, r; - unsigned int delta1, delta2; + uint8_t *pcurrent, *pabove, *pncurrent, *pnabove, *pbelow; + const unsigned int row_width = width*4; + const uint8_t* const max_ptr = col1 + (row_width * (height-1)); + const uint8_t *max_ptr2; + unsigned int b, g, r; + unsigned int delta1, delta2; - pcurrent = col1 + row_width; - pncurrent = col2 + row_width; - pabove = col1; - pnabove = col2; - pbelow = col1 + (row_width*2); - while(pcurrent < max_ptr) - { - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - b = abs(pnabove[1] - pabove[1]); - g = abs(pnabove[2] - pabove[2]); - r = abs(pnabove[3] - pabove[3]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - b = abs(pncurrent[1] - pcurrent[1]); - g = abs(pncurrent[2] - pcurrent[2]); - r = abs(pncurrent[3] - pcurrent[3]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; - pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; - pcurrent[3] = (pabove[3] + pbelow[3]) >> 1; - } - pabove += 4; - pnabove += 4; - pcurrent += 4; - pncurrent += 4; - pbelow += 4; - } - pcurrent += row_width; - pncurrent += row_width; - pabove += row_width; - pnabove += row_width; - pbelow += row_width; - - } - - /* Special case for the last line */ - max_ptr2 = pcurrent + row_width; - while(pcurrent < max_ptr2) { - b = abs(pnabove[1] - pabove[1]); - g = abs(pnabove[2] - pabove[2]); - r = abs(pnabove[3] - pabove[3]); - delta1 = (r + r + b + g + g + g + g + g)>>3; - b = abs(pncurrent[1] - pcurrent[1]); - g = abs(pncurrent[2] - pcurrent[2]); - r = abs(pncurrent[3] - pcurrent[3]); - delta2 = (r + r + b + g + g + g + g + g)>>3; - if(((delta1 + delta2) >> 1) >= threshold) { - pcurrent[1] = pabove[1]; - pcurrent[2] = pabove[2]; - pcurrent[3] = pabove[3]; - } - pabove += 4; - pnabove += 4; - pcurrent += 4; - pncurrent += 4; - } + pcurrent = col1 + row_width; + pncurrent = col2 + row_width; + pabove = col1; + pnabove = col2; + pbelow = col1 + (row_width*2); + while(pcurrent < max_ptr) + { + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + b = abs(pnabove[1] - pabove[1]); + g = abs(pnabove[2] - pabove[2]); + r = abs(pnabove[3] - pabove[3]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + b = abs(pncurrent[1] - pcurrent[1]); + g = abs(pncurrent[2] - pcurrent[2]); + r = abs(pncurrent[3] - pcurrent[3]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[1] = (pabove[1] + pbelow[1]) >> 1; + pcurrent[2] = (pabove[2] + pbelow[2]) >> 1; + pcurrent[3] = (pabove[3] + pbelow[3]) >> 1; + } + pabove += 4; + pnabove += 4; + pcurrent += 4; + pncurrent += 4; + pbelow += 4; + } + pcurrent += row_width; + pncurrent += row_width; + pabove += row_width; + pnabove += row_width; + pbelow += row_width; + + } + + /* Special case for the last line */ + max_ptr2 = pcurrent + row_width; + while(pcurrent < max_ptr2) { + b = abs(pnabove[1] - pabove[1]); + g = abs(pnabove[2] - pabove[2]); + r = abs(pnabove[3] - pabove[3]); + delta1 = (r + r + b + g + g + g + g + g)>>3; + b = abs(pncurrent[1] - pcurrent[1]); + g = abs(pncurrent[2] - pcurrent[2]); + r = abs(pncurrent[3] - pcurrent[3]); + delta2 = (r + r + b + g + g + g + g + g)>>3; + if(((delta1 + delta2) >> 1) >= threshold) { + pcurrent[1] = pabove[1]; + pcurrent[2] = pabove[2]; + pcurrent[3] = pabove[3]; + } + pabove += 4; + pnabove += 4; + pcurrent += 4; + pncurrent += 4; + } } /* Grayscale SSSE3 */ @@ -4825,132 +4825,132 @@ __attribute__((noinline,__target__("ssse3"))) void ssse3_deinterlace_4field_gray8(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - union { - uint32_t int32; - uint8_t int8a[4]; - } threshold_mask; - threshold_mask.int8a[0] = threshold; - threshold_mask.int8a[1] = 0; - threshold_mask.int8a[2] = threshold; - threshold_mask.int8a[3] = 0; + union { + uint32_t int32; + uint8_t int8a[4]; + } threshold_mask; + threshold_mask.int8a[0] = threshold; + threshold_mask.int8a[1] = 0; + threshold_mask.int8a[2] = threshold; + threshold_mask.int8a[3] = 0; - unsigned long row_width = width; - uint8_t* max_ptr = col1 + (row_width * (height-2)); - uint8_t* max_ptr2 = col1 + row_width; + unsigned long row_width = width; + uint8_t* max_ptr = col1 + (row_width * (height-2)); + uint8_t* max_ptr2 = col1 + row_width; - __asm__ __volatile__ ( - /* Load the threshold */ - "mov %5, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - /* Zero the temporary register */ - "pxor %%xmm0, %%xmm0\n\t" + __asm__ __volatile__ ( + /* Load the threshold */ + "mov %5, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + /* Zero the temporary register */ + "pxor %%xmm0, %%xmm0\n\t" - "algo_ssse3_deinterlace_4field_gray8:\n\t" + "algo_ssse3_deinterlace_4field_gray8:\n\t" - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "pmaxub %%xmm2, %%xmm1\n\t" - "pminub %%xmm5, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "pmaxub %%xmm2, %%xmm1\n\t" + "pminub %%xmm5, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "pmaxub %%xmm2, %%xmm1\n\t" - "pminub %%xmm6, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "pmaxub %%xmm2, %%xmm1\n\t" + "pminub %%xmm6, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together - "movdqa %%xmm1, %%xmm2\n\t" + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "movdqa %%xmm1, %%xmm2\n\t" - /* Do the comparison on words instead of bytes because we don't have unsigned comparison */ - "punpcklbw %%xmm0, %%xmm1\n\t" // Expand pixels 0-7 into words into xmm1 - "punpckhbw %%xmm0, %%xmm2\n\t" // Expand pixels 8-15 into words into xmm2 - "pcmpgtw %%xmm4, %%xmm1\n\t" // Compare average delta with threshold for pixels 0-7 - "pcmpgtw %%xmm4, %%xmm2\n\t" // Compare average delta with threshold for pixels 8-15 - "packsswb %%xmm2, %%xmm1\n\t" // Pack the comparison results into xmm1 + /* Do the comparison on words instead of bytes because we don't have unsigned comparison */ + "punpcklbw %%xmm0, %%xmm1\n\t" // Expand pixels 0-7 into words into xmm1 + "punpckhbw %%xmm0, %%xmm2\n\t" // Expand pixels 8-15 into words into xmm2 + "pcmpgtw %%xmm4, %%xmm1\n\t" // Compare average delta with threshold for pixels 0-7 + "pcmpgtw %%xmm4, %%xmm2\n\t" // Compare average delta with threshold for pixels 8-15 + "packsswb %%xmm2, %%xmm1\n\t" // Pack the comparison results into xmm1 - "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow - "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow - "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow + "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow + "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - "sub %4, %0\n\t" // Restore pcurrent to pabove - "sub %4, %1\n\t" // Restore pncurrent to pnabove + "sub %4, %0\n\t" // Restore pcurrent to pabove + "sub %4, %1\n\t" // Restore pncurrent to pnabove - /* Next pixels */ - "add $0x10, %0\n\t" // Add 16 to pcurrent - "add $0x10, %1\n\t" // Add 16 to pncurrent + /* Next pixels */ + "add $0x10, %0\n\t" // Add 16 to pcurrent + "add $0x10, %1\n\t" // Add 16 to pncurrent - /* Check if we reached the row end */ - "cmp %2, %0\n\t" - "jb algo_ssse3_deinterlace_4field_gray8\n\t" // Go for another iteration + /* Check if we reached the row end */ + "cmp %2, %0\n\t" + "jb algo_ssse3_deinterlace_4field_gray8\n\t" // Go for another iteration - /* Next row */ - "add %4, %0\n\t" // Add width to pcurrent - "add %4, %1\n\t" // Add width to pncurrent - "mov %0, %2\n\t" - "add %4, %2\n\t" // Add width to max_ptr2 + /* Next row */ + "add %4, %0\n\t" // Add width to pcurrent + "add %4, %1\n\t" // Add width to pncurrent + "mov %0, %2\n\t" + "add %4, %2\n\t" // Add width to max_ptr2 - /* Check if we reached the end */ - "cmp %3, %0\n\t" - "jb algo_ssse3_deinterlace_4field_gray8\n\t" // Go for another iteration + /* Check if we reached the end */ + "cmp %3, %0\n\t" + "jb algo_ssse3_deinterlace_4field_gray8\n\t" // Go for another iteration - /* Special case for the last line */ - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "pmaxub %%xmm2, %%xmm1\n\t" - "pminub %%xmm5, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Special case for the last line */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "pmaxub %%xmm2, %%xmm1\n\t" + "pminub %%xmm5, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "pmaxub %%xmm2, %%xmm1\n\t" - "pminub %%xmm6, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "pmaxub %%xmm2, %%xmm1\n\t" + "pminub %%xmm6, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together - "movdqa %%xmm1, %%xmm2\n\t" + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "movdqa %%xmm1, %%xmm2\n\t" - /* Do the comparison on words instead of bytes because we don't have unsigned comparison */ - "punpcklbw %%xmm0, %%xmm1\n\t" // Expand pixels 0-7 into words into xmm1 - "punpckhbw %%xmm0, %%xmm2\n\t" // Expand pixels 8-15 into words into xmm2 - "pcmpgtw %%xmm4, %%xmm1\n\t" // Compare average delta with threshold for pixels 0-7 - "pcmpgtw %%xmm4, %%xmm2\n\t" // Compare average delta with threshold for pixels 8-15 - "packsswb %%xmm2, %%xmm1\n\t" // Pack the comparison results into xmm1 + /* Do the comparison on words instead of bytes because we don't have unsigned comparison */ + "punpcklbw %%xmm0, %%xmm1\n\t" // Expand pixels 0-7 into words into xmm1 + "punpckhbw %%xmm0, %%xmm2\n\t" // Expand pixels 8-15 into words into xmm2 + "pcmpgtw %%xmm4, %%xmm1\n\t" // Compare average delta with threshold for pixels 0-7 + "pcmpgtw %%xmm4, %%xmm2\n\t" // Compare average delta with threshold for pixels 8-15 + "packsswb %%xmm2, %%xmm1\n\t" // Pack the comparison results into xmm1 - "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - : - : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_mask.int32) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" - ); + "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + : + : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_mask.int32) + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -4960,180 +4960,180 @@ __attribute__((noinline,__target__("ssse3"))) #endif void ssse3_deinterlace_4field_rgba(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __attribute__((aligned(16))) static const uint8_t movemask2[16] = {1,1,1,1,1,0,0,2,9,9,9,9,9,8,8,10}; + __attribute__((aligned(16))) static const uint8_t movemask2[16] = {1,1,1,1,1,0,0,2,9,9,9,9,9,8,8,10}; - const uint32_t threshold_val = threshold; + const uint32_t threshold_val = threshold; - unsigned long row_width = width*4; - uint8_t* max_ptr = col1 + (row_width * (height-2)); - uint8_t* max_ptr2 = col1 + row_width; + unsigned long row_width = width*4; + uint8_t* max_ptr = col1 + (row_width * (height-2)); + uint8_t* max_ptr2 = col1 + row_width; - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "movdqa %6, %%xmm3\n\t" - "mov %5, %%eax\n\t" + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "movdqa %6, %%xmm3\n\t" + "mov %5, %%eax\n\t" #if defined(__x86_64__) - "movd %%eax, %%xmm8\n\t" - "pshufd $0x0, %%xmm8, %%xmm8\n\t" + "movd %%eax, %%xmm8\n\t" + "pshufd $0x0, %%xmm8, %%xmm8\n\t" #endif - /* Zero the temporary register */ - "pxor %%xmm0, %%xmm0\n\t" + /* Zero the temporary register */ + "pxor %%xmm0, %%xmm0\n\t" - "algo_ssse3_deinterlace_4field_rgba:\n\t" + "algo_ssse3_deinterlace_4field_rgba:\n\t" - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together #if defined(__x86_64__) - "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold #else - "movd %%eax, %%xmm7\n\t" // Setup the threshold - "pshufd $0x0, %%xmm7, %%xmm7\n\t" + "movd %%eax, %%xmm7\n\t" // Setup the threshold + "pshufd $0x0, %%xmm7, %%xmm7\n\t" - "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold #endif - "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow - "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow - "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow + "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow + "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - "sub %4, %0\n\t" // Restore pcurrent to pabove - "sub %4, %1\n\t" // Restore pncurrent to pnabove + "sub %4, %0\n\t" // Restore pcurrent to pabove + "sub %4, %1\n\t" // Restore pncurrent to pnabove - /* Next pixels */ - "add $0x10, %0\n\t" // Add 16 to pcurrent - "add $0x10, %1\n\t" // Add 16 to pncurrent + /* Next pixels */ + "add $0x10, %0\n\t" // Add 16 to pcurrent + "add $0x10, %1\n\t" // Add 16 to pncurrent - /* Check if we reached the row end */ - "cmp %2, %0\n\t" - "jb algo_ssse3_deinterlace_4field_rgba\n\t" // Go for another iteration + /* Check if we reached the row end */ + "cmp %2, %0\n\t" + "jb algo_ssse3_deinterlace_4field_rgba\n\t" // Go for another iteration - /* Next row */ - "add %4, %0\n\t" // Add width to pcurrent - "add %4, %1\n\t" // Add width to pncurrent - "mov %0, %2\n\t" - "add %4, %2\n\t" // Add width to max_ptr2 + /* Next row */ + "add %4, %0\n\t" // Add width to pcurrent + "add %4, %1\n\t" // Add width to pncurrent + "mov %0, %2\n\t" + "add %4, %2\n\t" // Add width to max_ptr2 - /* Check if we reached the end */ - "cmp %3, %0\n\t" - "jb algo_ssse3_deinterlace_4field_rgba\n\t" // Go for another iteration + /* Check if we reached the end */ + "cmp %3, %0\n\t" + "jb algo_ssse3_deinterlace_4field_rgba\n\t" // Go for another iteration - /* Special case for the last line */ - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Special case for the last line */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together #if defined(__x86_64__) - "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold #else - "movd %%eax, %%xmm7\n\t" // Setup the threshold - "pshufd $0x0, %%xmm7, %%xmm7\n\t" + "movd %%eax, %%xmm7\n\t" // Setup the threshold + "pshufd $0x0, %%xmm7, %%xmm7\n\t" - "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold #endif - "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - : - : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_val), "m" (*movemask2) + "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + : + : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_val), "m" (*movemask2) #if defined(__x86_64__) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "cc", "memory" + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "cc", "memory" #else - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" #endif - ); + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -5143,180 +5143,180 @@ __attribute__((noinline,__target__("ssse3"))) #endif void ssse3_deinterlace_4field_bgra(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __attribute__((aligned(16))) static const uint8_t movemask2[16] = {1,1,1,1,1,2,2,0,9,9,9,9,9,10,10,8}; + __attribute__((aligned(16))) static const uint8_t movemask2[16] = {1,1,1,1,1,2,2,0,9,9,9,9,9,10,10,8}; - const uint32_t threshold_val = threshold; + const uint32_t threshold_val = threshold; - unsigned long row_width = width*4; - uint8_t* max_ptr = col1 + (row_width * (height-2)); - uint8_t* max_ptr2 = col1 + row_width; + unsigned long row_width = width*4; + uint8_t* max_ptr = col1 + (row_width * (height-2)); + uint8_t* max_ptr2 = col1 + row_width; - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "movdqa %6, %%xmm3\n\t" - "mov %5, %%eax\n\t" + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "movdqa %6, %%xmm3\n\t" + "mov %5, %%eax\n\t" #if defined(__x86_64__) - "movd %%eax, %%xmm8\n\t" - "pshufd $0x0, %%xmm8, %%xmm8\n\t" + "movd %%eax, %%xmm8\n\t" + "pshufd $0x0, %%xmm8, %%xmm8\n\t" #endif - /* Zero the temporary register */ - "pxor %%xmm0, %%xmm0\n\t" + /* Zero the temporary register */ + "pxor %%xmm0, %%xmm0\n\t" - "algo_ssse3_deinterlace_4field_bgra:\n\t" + "algo_ssse3_deinterlace_4field_bgra:\n\t" - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together #if defined(__x86_64__) - "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold #else - "movd %%eax, %%xmm7\n\t" // Setup the threshold - "pshufd $0x0, %%xmm7, %%xmm7\n\t" + "movd %%eax, %%xmm7\n\t" // Setup the threshold + "pshufd $0x0, %%xmm7, %%xmm7\n\t" - "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold #endif - "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow - "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow - "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow + "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow + "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - "sub %4, %0\n\t" // Restore pcurrent to pabove - "sub %4, %1\n\t" // Restore pncurrent to pnabove + "sub %4, %0\n\t" // Restore pcurrent to pabove + "sub %4, %1\n\t" // Restore pncurrent to pnabove - /* Next pixels */ - "add $0x10, %0\n\t" // Add 16 to pcurrent - "add $0x10, %1\n\t" // Add 16 to pncurrent + /* Next pixels */ + "add $0x10, %0\n\t" // Add 16 to pcurrent + "add $0x10, %1\n\t" // Add 16 to pncurrent - /* Check if we reached the row end */ - "cmp %2, %0\n\t" - "jb algo_ssse3_deinterlace_4field_bgra\n\t" // Go for another iteration + /* Check if we reached the row end */ + "cmp %2, %0\n\t" + "jb algo_ssse3_deinterlace_4field_bgra\n\t" // Go for another iteration - /* Next row */ - "add %4, %0\n\t" // Add width to pcurrent - "add %4, %1\n\t" // Add width to pncurrent - "mov %0, %2\n\t" - "add %4, %2\n\t" // Add width to max_ptr2 + /* Next row */ + "add %4, %0\n\t" // Add width to pcurrent + "add %4, %1\n\t" // Add width to pncurrent + "mov %0, %2\n\t" + "add %4, %2\n\t" // Add width to max_ptr2 - /* Check if we reached the end */ - "cmp %3, %0\n\t" - "jb algo_ssse3_deinterlace_4field_bgra\n\t" // Go for another iteration + /* Check if we reached the end */ + "cmp %3, %0\n\t" + "jb algo_ssse3_deinterlace_4field_bgra\n\t" // Go for another iteration - /* Special case for the last line */ - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Special case for the last line */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together #if defined(__x86_64__) - "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold #else - "movd %%eax, %%xmm7\n\t" // Setup the threshold - "pshufd $0x0, %%xmm7, %%xmm7\n\t" + "movd %%eax, %%xmm7\n\t" // Setup the threshold + "pshufd $0x0, %%xmm7, %%xmm7\n\t" - "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold #endif - "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - : - : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_val), "m" (*movemask2) + "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + : + : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_val), "m" (*movemask2) #if defined(__x86_64__) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "cc", "memory" + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "cc", "memory" #else - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" #endif - ); + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -5326,180 +5326,180 @@ __attribute__((noinline,__target__("ssse3"))) #endif void ssse3_deinterlace_4field_argb(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __attribute__((aligned(16))) static const uint8_t movemask2[16] = {2,2,2,2,2,1,1,3,10,10,10,10,10,9,9,11}; + __attribute__((aligned(16))) static const uint8_t movemask2[16] = {2,2,2,2,2,1,1,3,10,10,10,10,10,9,9,11}; - const uint32_t threshold_val = threshold; + const uint32_t threshold_val = threshold; - unsigned long row_width = width*4; - uint8_t* max_ptr = col1 + (row_width * (height-2)); - uint8_t* max_ptr2 = col1 + row_width; + unsigned long row_width = width*4; + uint8_t* max_ptr = col1 + (row_width * (height-2)); + uint8_t* max_ptr2 = col1 + row_width; - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "movdqa %6, %%xmm3\n\t" - "mov %5, %%eax\n\t" + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "movdqa %6, %%xmm3\n\t" + "mov %5, %%eax\n\t" #if defined(__x86_64__) - "movd %%eax, %%xmm8\n\t" - "pshufd $0x0, %%xmm8, %%xmm8\n\t" + "movd %%eax, %%xmm8\n\t" + "pshufd $0x0, %%xmm8, %%xmm8\n\t" #endif - /* Zero the temporary register */ - "pxor %%xmm0, %%xmm0\n\t" + /* Zero the temporary register */ + "pxor %%xmm0, %%xmm0\n\t" - "algo_ssse3_deinterlace_4field_argb:\n\t" + "algo_ssse3_deinterlace_4field_argb:\n\t" - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together #if defined(__x86_64__) - "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold #else - "movd %%eax, %%xmm7\n\t" // Setup the threshold - "pshufd $0x0, %%xmm7, %%xmm7\n\t" + "movd %%eax, %%xmm7\n\t" // Setup the threshold + "pshufd $0x0, %%xmm7, %%xmm7\n\t" - "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold #endif - "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow - "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow - "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow + "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow + "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - "sub %4, %0\n\t" // Restore pcurrent to pabove - "sub %4, %1\n\t" // Restore pncurrent to pnabove + "sub %4, %0\n\t" // Restore pcurrent to pabove + "sub %4, %1\n\t" // Restore pncurrent to pnabove - /* Next pixels */ - "add $0x10, %0\n\t" // Add 16 to pcurrent - "add $0x10, %1\n\t" // Add 16 to pncurrent + /* Next pixels */ + "add $0x10, %0\n\t" // Add 16 to pcurrent + "add $0x10, %1\n\t" // Add 16 to pncurrent - /* Check if we reached the row end */ - "cmp %2, %0\n\t" - "jb algo_ssse3_deinterlace_4field_argb\n\t" // Go for another iteration + /* Check if we reached the row end */ + "cmp %2, %0\n\t" + "jb algo_ssse3_deinterlace_4field_argb\n\t" // Go for another iteration - /* Next row */ - "add %4, %0\n\t" // Add width to pcurrent - "add %4, %1\n\t" // Add width to pncurrent - "mov %0, %2\n\t" - "add %4, %2\n\t" // Add width to max_ptr2 + /* Next row */ + "add %4, %0\n\t" // Add width to pcurrent + "add %4, %1\n\t" // Add width to pncurrent + "mov %0, %2\n\t" + "add %4, %2\n\t" // Add width to max_ptr2 - /* Check if we reached the end */ - "cmp %3, %0\n\t" - "jb algo_ssse3_deinterlace_4field_argb\n\t" // Go for another iteration + /* Check if we reached the end */ + "cmp %3, %0\n\t" + "jb algo_ssse3_deinterlace_4field_argb\n\t" // Go for another iteration - /* Special case for the last line */ - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Special case for the last line */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together #if defined(__x86_64__) - "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold #else - "movd %%eax, %%xmm7\n\t" // Setup the threshold - "pshufd $0x0, %%xmm7, %%xmm7\n\t" + "movd %%eax, %%xmm7\n\t" // Setup the threshold + "pshufd $0x0, %%xmm7, %%xmm7\n\t" - "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold #endif - "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - : - : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_val), "m" (*movemask2) + "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + : + : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_val), "m" (*movemask2) #if defined(__x86_64__) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "cc", "memory" + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "cc", "memory" #else - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" #endif - ); + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } @@ -5509,179 +5509,179 @@ __attribute__((noinline,__target__("ssse3"))) #endif void ssse3_deinterlace_4field_abgr(uint8_t* col1, uint8_t* col2, unsigned int threshold, unsigned int width, unsigned int height) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - __attribute__((aligned(16))) static const uint8_t movemask2[16] = {2,2,2,2,2,3,3,1,10,10,10,10,10,11,11,9}; + __attribute__((aligned(16))) static const uint8_t movemask2[16] = {2,2,2,2,2,3,3,1,10,10,10,10,10,11,11,9}; - const uint32_t threshold_val = threshold; + const uint32_t threshold_val = threshold; - unsigned long row_width = width*4; - uint8_t* max_ptr = col1 + (row_width * (height-2)); - uint8_t* max_ptr2 = col1 + row_width; + unsigned long row_width = width*4; + uint8_t* max_ptr = col1 + (row_width * (height-2)); + uint8_t* max_ptr2 = col1 + row_width; - __asm__ __volatile__ ( - "mov $0x1F1F1F1F, %%eax\n\t" - "movd %%eax, %%xmm4\n\t" - "pshufd $0x0, %%xmm4, %%xmm4\n\t" - "movdqa %6, %%xmm3\n\t" - "mov %5, %%eax\n\t" + __asm__ __volatile__ ( + "mov $0x1F1F1F1F, %%eax\n\t" + "movd %%eax, %%xmm4\n\t" + "pshufd $0x0, %%xmm4, %%xmm4\n\t" + "movdqa %6, %%xmm3\n\t" + "mov %5, %%eax\n\t" #if defined(__x86_64__) - "movd %%eax, %%xmm8\n\t" - "pshufd $0x0, %%xmm8, %%xmm8\n\t" + "movd %%eax, %%xmm8\n\t" + "pshufd $0x0, %%xmm8, %%xmm8\n\t" #endif - /* Zero the temporary register */ - "pxor %%xmm0, %%xmm0\n\t" + /* Zero the temporary register */ + "pxor %%xmm0, %%xmm0\n\t" - "algo_ssse3_deinterlace_4field_abgr:\n\t" + "algo_ssse3_deinterlace_4field_abgr:\n\t" - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together #if defined(__x86_64__) - "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold #else - "movd %%eax, %%xmm7\n\t" // Setup the threshold - "pshufd $0x0, %%xmm7, %%xmm7\n\t" + "movd %%eax, %%xmm7\n\t" // Setup the threshold + "pshufd $0x0, %%xmm7, %%xmm7\n\t" - "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold #endif - "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow - "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow - "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "movdqa (%0,%4), %%xmm2\n\t" // Load pbelow + "pavgb %%xmm5, %%xmm2\n\t" // Average pabove and pbelow + "pand %%xmm1, %%xmm2\n\t" // Filter out pixels in avg that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + "por %%xmm2, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - "sub %4, %0\n\t" // Restore pcurrent to pabove - "sub %4, %1\n\t" // Restore pncurrent to pnabove + "sub %4, %0\n\t" // Restore pcurrent to pabove + "sub %4, %1\n\t" // Restore pncurrent to pnabove - /* Next pixels */ - "add $0x10, %0\n\t" // Add 16 to pcurrent - "add $0x10, %1\n\t" // Add 16 to pncurrent + /* Next pixels */ + "add $0x10, %0\n\t" // Add 16 to pcurrent + "add $0x10, %1\n\t" // Add 16 to pncurrent - /* Check if we reached the row end */ - "cmp %2, %0\n\t" - "jb algo_ssse3_deinterlace_4field_abgr\n\t" // Go for another iteration + /* Check if we reached the row end */ + "cmp %2, %0\n\t" + "jb algo_ssse3_deinterlace_4field_abgr\n\t" // Go for another iteration - /* Next row */ - "add %4, %0\n\t" // Add width to pcurrent - "add %4, %1\n\t" // Add width to pncurrent - "mov %0, %2\n\t" - "add %4, %2\n\t" // Add width to max_ptr2 + /* Next row */ + "add %4, %0\n\t" // Add width to pcurrent + "add %4, %1\n\t" // Add width to pncurrent + "mov %0, %2\n\t" + "add %4, %2\n\t" // Add width to max_ptr2 - /* Check if we reached the end */ - "cmp %3, %0\n\t" - "jb algo_ssse3_deinterlace_4field_abgr\n\t" // Go for another iteration + /* Check if we reached the end */ + "cmp %3, %0\n\t" + "jb algo_ssse3_deinterlace_4field_abgr\n\t" // Go for another iteration - /* Special case for the last line */ - /* Load pabove into xmm1 and pnabove into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" - "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ + /* Special case for the last line */ + /* Load pabove into xmm1 and pnabove into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm5\n\t" /* Keep backup of pabove in xmm5 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" + "movdqa %%xmm1, %%xmm7\n\t" /* Backup of delta2 in xmm7 for now */ - /* Next row */ - "add %4, %0\n\t" - "add %4, %1\n\t" + /* Next row */ + "add %4, %0\n\t" + "add %4, %1\n\t" - /* Load pcurrent into xmm1 and pncurrent into xmm2 */ - "movdqa (%0), %%xmm1\n\t" - "movdqa (%1), %%xmm2\n\t" - "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ - "psrlq $0x3, %%xmm1\n\t" - "psrlq $0x3, %%xmm2\n\t" - "pand %%xmm4, %%xmm1\n\t" - "pand %%xmm4, %%xmm2\n\t" - "psubb %%xmm2, %%xmm1\n\t" - "pabsb %%xmm1, %%xmm2\n\t" - "movdqa %%xmm2, %%xmm1\n\t" - "punpckldq %%xmm1, %%xmm1\n\t" - "pshufb %%xmm3, %%xmm1\n\t" - "psadbw %%xmm0, %%xmm1\n\t" - "punpckhdq %%xmm2, %%xmm2\n\t" - "pshufb %%xmm3, %%xmm2\n\t" - "psadbw %%xmm0, %%xmm2\n\t" - "packuswb %%xmm2, %%xmm1\n\t" + /* Load pcurrent into xmm1 and pncurrent into xmm2 */ + "movdqa (%0), %%xmm1\n\t" + "movdqa (%1), %%xmm2\n\t" + "movdqa %%xmm1, %%xmm6\n\t" /* Keep backup of pcurrent in xmm6 */ + "psrlq $0x3, %%xmm1\n\t" + "psrlq $0x3, %%xmm2\n\t" + "pand %%xmm4, %%xmm1\n\t" + "pand %%xmm4, %%xmm2\n\t" + "psubb %%xmm2, %%xmm1\n\t" + "pabsb %%xmm1, %%xmm2\n\t" + "movdqa %%xmm2, %%xmm1\n\t" + "punpckldq %%xmm1, %%xmm1\n\t" + "pshufb %%xmm3, %%xmm1\n\t" + "psadbw %%xmm0, %%xmm1\n\t" + "punpckhdq %%xmm2, %%xmm2\n\t" + "pshufb %%xmm3, %%xmm2\n\t" + "psadbw %%xmm0, %%xmm2\n\t" + "packuswb %%xmm2, %%xmm1\n\t" - "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together + "pavgb %%xmm7, %%xmm1\n\t" // Average the two deltas together #if defined(__x86_64__) - "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm8, %%xmm1\n\t" // Compare average delta with the threshold #else - "movd %%eax, %%xmm7\n\t" // Setup the threshold - "pshufd $0x0, %%xmm7, %%xmm7\n\t" + "movd %%eax, %%xmm7\n\t" // Setup the threshold + "pshufd $0x0, %%xmm7, %%xmm7\n\t" - "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold + "pcmpgtd %%xmm7, %%xmm1\n\t" // Compare average delta with the threshold #endif - "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied - "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced + "pand %%xmm1, %%xmm5\n\t" // Filter out pixels in pabove that shouldn't be copied + "pandn %%xmm6, %%xmm1\n\t" // Filter out pixels in pcurrent that should be replaced - "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent - "movntdq %%xmm1, (%0)\n\t" // Write pcurrent - : - : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_val), "m" (*movemask2) + "por %%xmm5, %%xmm1\n\t" // Put the new values in pcurrent + "movntdq %%xmm1, (%0)\n\t" // Write pcurrent + : + : "r" (col1), "r" (col2), "r" (max_ptr2), "r" (max_ptr), "r" (row_width), "m" (threshold_val), "m" (*movemask2) #if defined(__x86_64__) - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "cc", "memory" + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "cc", "memory" #else - : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" + : "%eax", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" #endif - ); + ); #else - Panic("SSE function called on a non x86\\x86-64 platform"); + Panic("SSE function called on a non x86\\x86-64 platform"); #endif } diff --git a/src/zm_image_analyser.cpp b/src/zm_image_analyser.cpp index 1445e9864..8f03160d9 100644 --- a/src/zm_image_analyser.cpp +++ b/src/zm_image_analyser.cpp @@ -7,7 +7,7 @@ */ ImageAnalyser::ImageAnalyser(const ImageAnalyser& source) { - m_Detectors = source.m_Detectors; + m_Detectors = source.m_Detectors; } @@ -17,18 +17,18 @@ ImageAnalyser::ImageAnalyser(const ImageAnalyser& source) */ ImageAnalyser& ImageAnalyser::operator=(const ImageAnalyser& source) { - m_Detectors = source.m_Detectors; - return *this; + m_Detectors = source.m_Detectors; + return *this; } ImageAnalyser::~ImageAnalyser() { - for(DetectorsList::reverse_iterator It = m_Detectors.rbegin(); - It != m_Detectors.rend(); - ++It) - delete *It; + for(DetectorsList::reverse_iterator It = m_Detectors.rbegin(); + It != m_Detectors.rend(); + ++It) + delete *It; } @@ -42,23 +42,23 @@ ImageAnalyser::~ImageAnalyser() */ int ImageAnalyser::DoDetection(const Image &comp_image, Zone** zones, int n_numZones, Event::StringSetMap noteSetMap, std::string& det_cause) { - Event::StringSet zoneSet; - int score = 0; + Event::StringSet zoneSet; + int score = 0; - for(DetectorsList::iterator It = m_Detectors.begin(); - It != m_Detectors.end(); - ++It) + for(DetectorsList::iterator It = m_Detectors.begin(); + It != m_Detectors.end(); + ++It) + { + int detect_score = (*It)->Detect(comp_image, zones, n_numZones, zoneSet); + if (detect_score) { - int detect_score = (*It)->Detect(comp_image, zones, n_numZones, zoneSet); - if (detect_score) - { - score += detect_score; - noteSetMap[(*It)->getDetectionCause()] = zoneSet; - if (det_cause.length()) - det_cause += ", "; - det_cause += (*It)->getDetectionCause(); - } + score += detect_score; + noteSetMap[(*It)->getDetectionCause()] = zoneSet; + if (det_cause.length()) + det_cause += ", "; + det_cause += (*It)->getDetectionCause(); } - return score; + } + return score; } diff --git a/src/zm_image_analyser.h b/src/zm_image_analyser.h index 74cc7a73a..c853c82a3 100644 --- a/src/zm_image_analyser.h +++ b/src/zm_image_analyser.h @@ -22,18 +22,18 @@ using namespace std; //! Class for handling image detection. class ImageAnalyser { public: - - //!Default constructor. - ImageAnalyser() {}; + + //!Default constructor. + ImageAnalyser() {}; - //! Destructor. - ~ImageAnalyser(); + //! Destructor. + ~ImageAnalyser(); - //! Copy constructor. - ImageAnalyser(const ImageAnalyser& source); + //! Copy constructor. + ImageAnalyser(const ImageAnalyser& source); - //! Overloaded operator=. - ImageAnalyser& operator=(const ImageAnalyser& source); + //! Overloaded operator=. + ImageAnalyser& operator=(const ImageAnalyser& source); private: diff --git a/src/zm_jpeg.cpp b/src/zm_jpeg.cpp index 92f757ca1..c47bbe267 100644 --- a/src/zm_jpeg.cpp +++ b/src/zm_jpeg.cpp @@ -32,65 +32,65 @@ static int jpeg_err_count = 0; void zm_jpeg_error_exit( j_common_ptr cinfo ) { - static char buffer[JMSG_LENGTH_MAX]; - zm_error_ptr zmerr = (zm_error_ptr)cinfo->err; + static char buffer[JMSG_LENGTH_MAX]; + zm_error_ptr zmerr = (zm_error_ptr)cinfo->err; - (zmerr->pub.format_message)( cinfo, buffer ); + (zmerr->pub.format_message)( cinfo, buffer ); - Error( "%s", buffer ); - if ( ++jpeg_err_count == MAX_JPEG_ERRS ) - { - Fatal( "Maximum number (%d) of JPEG errors reached, exiting", jpeg_err_count ); - } + Error( "%s", buffer ); + if ( ++jpeg_err_count == MAX_JPEG_ERRS ) + { + Fatal( "Maximum number (%d) of JPEG errors reached, exiting", jpeg_err_count ); + } - longjmp( zmerr->setjmp_buffer, 1 ); + longjmp( zmerr->setjmp_buffer, 1 ); } void zm_jpeg_emit_message( j_common_ptr cinfo, int msg_level ) { - static char buffer[JMSG_LENGTH_MAX]; - zm_error_ptr zmerr = (zm_error_ptr)cinfo->err; + static char buffer[JMSG_LENGTH_MAX]; + zm_error_ptr zmerr = (zm_error_ptr)cinfo->err; - if ( msg_level < 0 ) - { - /* It's a warning message. Since corrupt files may generate many warnings, - * the policy implemented here is to show only the first warning, - * unless trace_level >= 3. - */ - if ( zmerr->pub.num_warnings == 0 || zmerr->pub.trace_level >= 3 ) - { - (zmerr->pub.format_message)( cinfo, buffer ); - if (!strstr(buffer, "Corrupt JPEG data:")) - Warning( "%s", buffer ); - } - /* Always count warnings in num_warnings. */ - zmerr->pub.num_warnings++; - } - else - { - /* It's a trace message. Show it if trace_level >= msg_level. */ - if ( zmerr->pub.trace_level >= msg_level ) - { - (zmerr->pub.format_message)( cinfo, buffer ); - Debug( msg_level, "%s", buffer ); - } - } + if ( msg_level < 0 ) + { + /* It's a warning message. Since corrupt files may generate many warnings, + * the policy implemented here is to show only the first warning, + * unless trace_level >= 3. + */ + if ( zmerr->pub.num_warnings == 0 || zmerr->pub.trace_level >= 3 ) + { + (zmerr->pub.format_message)( cinfo, buffer ); + if (!strstr(buffer, "Corrupt JPEG data:")) + Warning( "%s", buffer ); + } + /* Always count warnings in num_warnings. */ + zmerr->pub.num_warnings++; + } + else + { + /* It's a trace message. Show it if trace_level >= msg_level. */ + if ( zmerr->pub.trace_level >= msg_level ) + { + (zmerr->pub.format_message)( cinfo, buffer ); + Debug( msg_level, "%s", buffer ); + } + } } /* Expanded data destination object for memory */ typedef struct { - struct jpeg_destination_mgr pub; /* public fields */ + struct jpeg_destination_mgr pub; /* public fields */ - JOCTET *outbuffer; /* target buffer */ - int *outbuffer_size; - JOCTET *buffer; /* start of buffer */ + JOCTET *outbuffer; /* target buffer */ + int *outbuffer_size; + JOCTET *buffer; /* start of buffer */ } mem_destination_mgr; typedef mem_destination_mgr * mem_dest_ptr; -#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ /* * Initialize destination --- called by jpeg_start_compress @@ -99,15 +99,15 @@ typedef mem_destination_mgr * mem_dest_ptr; static void init_destination (j_compress_ptr cinfo) { - mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; - /* Allocate the output buffer --- it will be released when done with image */ - dest->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); + /* Allocate the output buffer --- it will be released when done with image */ + dest->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; - *(dest->outbuffer_size) = 0; + *(dest->outbuffer_size) = 0; } @@ -136,15 +136,15 @@ static void init_destination (j_compress_ptr cinfo) static boolean empty_output_buffer (j_compress_ptr cinfo) { - mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; - memcpy( dest->outbuffer+*(dest->outbuffer_size), dest->buffer, OUTPUT_BUF_SIZE ); - *(dest->outbuffer_size) += OUTPUT_BUF_SIZE; + memcpy( dest->outbuffer+*(dest->outbuffer_size), dest->buffer, OUTPUT_BUF_SIZE ); + *(dest->outbuffer_size) += OUTPUT_BUF_SIZE; - dest->pub.next_output_byte = dest->buffer; - dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; + dest->pub.next_output_byte = dest->buffer; + dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; - return( TRUE ); + return( TRUE ); } /* @@ -158,14 +158,14 @@ static boolean empty_output_buffer (j_compress_ptr cinfo) static void term_destination (j_compress_ptr cinfo) { - mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; - size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; + mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; + size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer; - if ( datacount > 0 ) - { - memcpy( dest->outbuffer+*(dest->outbuffer_size), dest->buffer, datacount ); - *(dest->outbuffer_size) += datacount; - } + if ( datacount > 0 ) + { + memcpy( dest->outbuffer+*(dest->outbuffer_size), dest->buffer, datacount ); + *(dest->outbuffer_size) += datacount; + } } @@ -177,45 +177,45 @@ static void term_destination (j_compress_ptr cinfo) void zm_jpeg_mem_dest (j_compress_ptr cinfo, JOCTET *outbuffer, int *outbuffer_size ) { - mem_dest_ptr dest; + mem_dest_ptr dest; - /* The destination object is made permanent so that multiple JPEG images - * can be written to the same file without re-executing jpeg_stdio_dest. - * This makes it dangerous to use this manager and a different destination - * manager serially with the same JPEG object, because their private object - * sizes may be different. Caveat programmer. - */ - if ( cinfo->dest == NULL ) - { - /* first time for this JPEG object? */ - cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_destination_mgr)); - } + /* The destination object is made permanent so that multiple JPEG images + * can be written to the same file without re-executing jpeg_stdio_dest. + * This makes it dangerous to use this manager and a different destination + * manager serially with the same JPEG object, because their private object + * sizes may be different. Caveat programmer. + */ + if ( cinfo->dest == NULL ) + { + /* first time for this JPEG object? */ + cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_destination_mgr)); + } - dest = (mem_dest_ptr) cinfo->dest; - dest->pub.init_destination = init_destination; - dest->pub.empty_output_buffer = empty_output_buffer; - dest->pub.term_destination = term_destination; - dest->outbuffer = outbuffer; - dest->outbuffer_size = outbuffer_size; + dest = (mem_dest_ptr) cinfo->dest; + dest->pub.init_destination = init_destination; + dest->pub.empty_output_buffer = empty_output_buffer; + dest->pub.term_destination = term_destination; + dest->outbuffer = outbuffer; + dest->outbuffer_size = outbuffer_size; } /* Expanded data source object for memory input */ typedef struct { - struct jpeg_source_mgr pub; /* public fields */ + struct jpeg_source_mgr pub; /* public fields */ - JOCTET * inbuffer; /* source stream */ - int inbuffer_size; - int inbuffer_size_hwm; /* High water mark */ + JOCTET * inbuffer; /* source stream */ + int inbuffer_size; + int inbuffer_size_hwm; /* High water mark */ - JOCTET * buffer; /* start of buffer */ - boolean start_of_data; /* have we gotten any data yet? */ + JOCTET * buffer; /* start of buffer */ + boolean start_of_data; /* have we gotten any data yet? */ } mem_source_mgr; typedef mem_source_mgr * mem_src_ptr; -#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ /* * Initialize source --- called by jpeg_read_header @@ -224,14 +224,14 @@ typedef mem_source_mgr * mem_src_ptr; static void init_source (j_decompress_ptr cinfo) { - mem_src_ptr src = (mem_src_ptr) cinfo->src; + mem_src_ptr src = (mem_src_ptr) cinfo->src; - /* We reset the empty-input-file flag for each image, - * but we don't clear the input buffer. - * This is correct behavior for reading a series of images from one source. - */ - src->start_of_data = TRUE; - src->pub.bytes_in_buffer = 0; + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_data = TRUE; + src->pub.bytes_in_buffer = 0; } @@ -270,26 +270,26 @@ static void init_source (j_decompress_ptr cinfo) static boolean fill_input_buffer (j_decompress_ptr cinfo) { - mem_src_ptr src = (mem_src_ptr) cinfo->src; - size_t nbytes; + mem_src_ptr src = (mem_src_ptr) cinfo->src; + size_t nbytes; - memcpy( src->buffer, src->inbuffer, (size_t) src->inbuffer_size ); - nbytes = src->inbuffer_size; + memcpy( src->buffer, src->inbuffer, (size_t) src->inbuffer_size ); + nbytes = src->inbuffer_size; - if ( nbytes <= 0 ) - { - if ( src->start_of_data ) /* Treat empty input file as fatal error */ - ERREXIT(cinfo, JERR_INPUT_EMPTY); - WARNMS(cinfo, JWRN_JPEG_EOF); - /* Insert a fake EOI marker */ - src->buffer[0] = (JOCTET) 0xFF; - src->buffer[1] = (JOCTET) JPEG_EOI; - nbytes = 2; - } + if ( nbytes <= 0 ) + { + if ( src->start_of_data ) /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } - src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = nbytes; - src->start_of_data = FALSE; + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_data = FALSE; return( TRUE ); } @@ -309,25 +309,25 @@ static boolean fill_input_buffer (j_decompress_ptr cinfo) static void skip_input_data (j_decompress_ptr cinfo, long num_bytes) { - mem_src_ptr src = (mem_src_ptr) cinfo->src; + mem_src_ptr src = (mem_src_ptr) cinfo->src; - /* Just a dumb implementation for now. Could use fseek() except - * it doesn't work on pipes. Not clear that being smart is worth - * any trouble anyway --- large skips are infrequent. - */ - if ( num_bytes > 0 ) + /* Just a dumb implementation for now. Could use fseek() except + * it doesn't work on pipes. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if ( num_bytes > 0 ) + { + while ( num_bytes > (long) src->pub.bytes_in_buffer ) { - while ( num_bytes > (long) src->pub.bytes_in_buffer ) - { - num_bytes -= (long) src->pub.bytes_in_buffer; - (void) fill_input_buffer(cinfo); - /* note we assume that fill_input_buffer will never return FALSE, - * so suspension need not be handled. - */ - } - src->pub.next_input_byte += (size_t) num_bytes; - src->pub.bytes_in_buffer -= (size_t) num_bytes; + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } } @@ -342,7 +342,7 @@ static void skip_input_data (j_decompress_ptr cinfo, long num_bytes) static void term_source (j_decompress_ptr cinfo) { - /* no work necessary here */ + /* no work necessary here */ } @@ -354,114 +354,114 @@ static void term_source (j_decompress_ptr cinfo) void zm_jpeg_mem_src( j_decompress_ptr cinfo, const JOCTET *inbuffer, int inbuffer_size ) { - mem_src_ptr src; - - /* The source object and input buffer are made permanent so that a series - * of JPEG images can be read from the same file by calling zm_jpeg_mem_src - * only before the first one. (If we discarded the buffer at the end of - * one image, we'd likely lose the start of the next one.) - * This makes it unsafe to use this manager and a different source - * manager serially with the same JPEG object. Caveat programmer. - */ - if ( cinfo->src == NULL ) - { - /* first time for this JPEG object? */ - cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_source_mgr)); - src = (mem_src_ptr) cinfo->src; - src->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, inbuffer_size * SIZEOF(JOCTET)); - src->inbuffer_size_hwm = inbuffer_size; - } - else - { - src = (mem_src_ptr) cinfo->src; - if ( src->inbuffer_size_hwm < inbuffer_size ) - { - src->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, inbuffer_size * SIZEOF(JOCTET)); - src->inbuffer_size_hwm = inbuffer_size; - } - } + mem_src_ptr src; + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling zm_jpeg_mem_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if ( cinfo->src == NULL ) + { + /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, SIZEOF(mem_source_mgr)); src = (mem_src_ptr) cinfo->src; - src->pub.init_source = init_source; - src->pub.fill_input_buffer = fill_input_buffer; - src->pub.skip_input_data = skip_input_data; - src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ - src->pub.term_source = term_source; - src->inbuffer = (JOCTET *)inbuffer; - src->inbuffer_size = inbuffer_size; - src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ - src->pub.next_input_byte = NULL; /* until buffer loaded */ + src->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, inbuffer_size * SIZEOF(JOCTET)); + src->inbuffer_size_hwm = inbuffer_size; + } + else + { + src = (mem_src_ptr) cinfo->src; + if ( src->inbuffer_size_hwm < inbuffer_size ) + { + src->buffer = (JOCTET *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, inbuffer_size * SIZEOF(JOCTET)); + src->inbuffer_size_hwm = inbuffer_size; + } + } + + src = (mem_src_ptr) cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + src->inbuffer = (JOCTET *)inbuffer; + src->inbuffer_size = inbuffer_size; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ } void zm_use_std_huff_tables( j_decompress_ptr cinfo ) { - /* JPEG standard Huffman tables (cf. JPEG standard section K.3) */ - /* IMPORTANT: these are only valid for 8-bit data precision! */ - static const JHUFF_TBL dclumin = { - { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, - FALSE - }; - static const JHUFF_TBL dcchrome = { - { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, - FALSE - }; - static const JHUFF_TBL aclumin = { - { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }, - { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }, - FALSE - }; - static const JHUFF_TBL acchrome = { - { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }, - { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa }, - FALSE - }; - - cinfo->dc_huff_tbl_ptrs[0] = (JHUFF_TBL*)&dclumin; - cinfo->dc_huff_tbl_ptrs[1] = (JHUFF_TBL*)&dcchrome; - cinfo->ac_huff_tbl_ptrs[0] = (JHUFF_TBL*)&aclumin; - cinfo->ac_huff_tbl_ptrs[1] = (JHUFF_TBL*)&acchrome; - + /* JPEG standard Huffman tables (cf. JPEG standard section K.3) */ + /* IMPORTANT: these are only valid for 8-bit data precision! */ + static const JHUFF_TBL dclumin = { + { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, + FALSE + }; + static const JHUFF_TBL dcchrome = { + { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, + FALSE + }; + static const JHUFF_TBL aclumin = { + { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }, + { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }, + FALSE + }; + static const JHUFF_TBL acchrome = { + { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }, + { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa }, + FALSE + }; + + cinfo->dc_huff_tbl_ptrs[0] = (JHUFF_TBL*)&dclumin; + cinfo->dc_huff_tbl_ptrs[1] = (JHUFF_TBL*)&dcchrome; + cinfo->ac_huff_tbl_ptrs[0] = (JHUFF_TBL*)&aclumin; + cinfo->ac_huff_tbl_ptrs[1] = (JHUFF_TBL*)&acchrome; + } } diff --git a/src/zm_jpeg.h b/src/zm_jpeg.h index 94290869a..b7807d0d3 100644 --- a/src/zm_jpeg.h +++ b/src/zm_jpeg.h @@ -32,8 +32,8 @@ extern "C" /* Stuff for overriden error handlers */ struct zm_error_mgr { - struct jpeg_error_mgr pub; - jmp_buf setjmp_buffer; + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; }; typedef struct zm_error_mgr *zm_error_ptr; diff --git a/src/zm_local_camera.cpp b/src/zm_local_camera.cpp index 1a22f4c8c..ca5f79472 100644 --- a/src/zm_local_camera.cpp +++ b/src/zm_local_camera.cpp @@ -644,7 +644,11 @@ LocalCamera::LocalCamera( if ( !tmpPicture ) Fatal( "Could not allocate temporary picture" ); - int pSize = avpicture_get_size( imagePixFormat, width, height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int pSize = av_image_get_buffer_size( imagePixFormat, width, height,1 ); +#else + int pSize = avpicture_get_size( imagePixFormat, width, height ); +#endif if( (unsigned int)pSize != imagesize) { Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); } @@ -877,7 +881,18 @@ void LocalCamera::Initialise() #endif if ( !capturePictures[i] ) Fatal( "Could not allocate picture" ); - avpicture_fill( (AVPicture *)capturePictures[i], (uint8_t*)v4l2_data.buffers[i].start, capturePixFormat, v4l2_data.fmt.fmt.pix.width, v4l2_data.fmt.fmt.pix.height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(capturePictures[i]->data, + capturePictures[i]->linesize, + (uint8_t*)v4l2_data.buffers[i].start,capturePixFormat, + v4l2_data.fmt.fmt.pix.width, + v4l2_data.fmt.fmt.pix.height, 1); +#else + avpicture_fill( (AVPicture *)capturePictures[i], + (uint8_t*)v4l2_data.buffers[i].start, capturePixFormat, + v4l2_data.fmt.fmt.pix.width, + v4l2_data.fmt.fmt.pix.height ); +#endif #endif // HAVE_LIBSWSCALE } @@ -1035,7 +1050,16 @@ void LocalCamera::Initialise() #endif if ( !capturePictures[i] ) Fatal( "Could not allocate picture" ); - avpicture_fill( (AVPicture *)capturePictures[i], (unsigned char *)v4l1_data.bufptr+v4l1_data.frames.offsets[i], capturePixFormat, width, height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(capturePictures[i]->data, + capturePictures[i]->linesize, + (unsigned char *)v4l1_data.bufptr+v4l1_data.frames.offsets[i], + capturePixFormat, width, height, 1); +#else + avpicture_fill( (AVPicture *)capturePictures[i], + (unsigned char *)v4l1_data.bufptr+v4l1_data.frames.offsets[i], + capturePixFormat, width, height ); +#endif } #endif // HAVE_LIBSWSCALE @@ -2131,7 +2155,14 @@ int LocalCamera::Capture( Image &image ) Debug( 9, "Calling sws_scale to perform the conversion" ); /* Use swscale to convert the image directly into the shared memory */ - avpicture_fill( (AVPicture *)tmpPicture, directbuffer, imagePixFormat, width, height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(tmpPicture->data, + tmpPicture->linesize, directbuffer, + imagePixFormat, width, height, 1); +#else + avpicture_fill( (AVPicture *)tmpPicture, directbuffer, + imagePixFormat, width, height ); +#endif sws_scale( imgConversionContext, capturePictures[capture_frame]->data, capturePictures[capture_frame]->linesize, 0, height, tmpPicture->data, tmpPicture->linesize ); } #endif diff --git a/src/zm_logger.cpp b/src/zm_logger.cpp index c4e0cceef..843dc7ac2 100644 --- a/src/zm_logger.cpp +++ b/src/zm_logger.cpp @@ -615,7 +615,7 @@ void Logger::logPrint( bool hex, const char * const filepath, const int line, co { int priority = smSyslogPriorities[level]; //priority |= LOG_DAEMON; - syslog( priority, "%s [%s]", classString, syslogStart ); + syslog( priority, "%s [%s] [%s]", classString, mId.c_str(), syslogStart ); } if ( level <= FATAL ) diff --git a/src/zm_logger.h b/src/zm_logger.h index 8477d61ed..d30396056 100644 --- a/src/zm_logger.h +++ b/src/zm_logger.h @@ -33,190 +33,190 @@ class Logger { public: - enum { - NOOPT=-6, - NOLOG, - PANIC, - FATAL, - ERROR, - WARNING, - INFO, - DEBUG1, - DEBUG2, - DEBUG3, - DEBUG4, - DEBUG5, - DEBUG6, - DEBUG7, - DEBUG8, - DEBUG9 - }; + enum { + NOOPT=-6, + NOLOG, + PANIC, + FATAL, + ERROR, + WARNING, + INFO, + DEBUG1, + DEBUG2, + DEBUG3, + DEBUG4, + DEBUG5, + DEBUG6, + DEBUG7, + DEBUG8, + DEBUG9 + }; - typedef int Level; + typedef int Level; - typedef std::map StringMap; - typedef std::map IntMap; + typedef std::map StringMap; + typedef std::map IntMap; - class Options - { - public: - int mTermLevel; - int mDatabaseLevel; - int mFileLevel; - int mSyslogLevel; + class Options + { + public: + int mTermLevel; + int mDatabaseLevel; + int mFileLevel; + int mSyslogLevel; - std::string mLogPath; - std::string mLogFile; - - public: - Options( Level termLevel=NOOPT, Level databaseLevel=NOOPT, Level fileLevel=NOOPT, Level syslogLevel=NOOPT, const std::string &logPath=".", const std::string &logFile="" ) : - mTermLevel( termLevel ), - mDatabaseLevel( databaseLevel ), - mFileLevel( fileLevel ), - mSyslogLevel( syslogLevel ), - mLogPath( logPath ), - mLogFile( logFile ) - { - } - }; - -private: - static bool smInitialised; - static Logger *smInstance; - - static StringMap smCodes; - static IntMap smSyslogPriorities; - -private: - bool mInitialised; - - std::string mId; - std::string mIdRoot; - std::string mIdArgs; - - Level mLevel; // Level that is currently in operation - Level mTermLevel; // Maximum level output via terminal - Level mDatabaseLevel; // Maximum level output via database - Level mFileLevel; // Maximum level output via file - Level mSyslogLevel; // Maximum level output via syslog - Level mEffectiveLevel; // Level optimised to take account of maxima - - bool mDbConnected; - MYSQL mDbConnection; std::string mLogPath; std::string mLogFile; - FILE *mLogFileFP; - bool mHasTerm; - bool mFlush; + public: + Options( Level termLevel=NOOPT, Level databaseLevel=NOOPT, Level fileLevel=NOOPT, Level syslogLevel=NOOPT, const std::string &logPath=".", const std::string &logFile="" ) : + mTermLevel( termLevel ), + mDatabaseLevel( databaseLevel ), + mFileLevel( fileLevel ), + mSyslogLevel( syslogLevel ), + mLogPath( logPath ), + mLogFile( logFile ) + { + } + }; private: - static void usrHandler( int sig ); + static bool smInitialised; + static Logger *smInstance; -public: - friend void logInit( const char *name, const Options &options ); - friend void logTerm(); - - static Logger *fetch() - { - if ( !smInstance ) - { - smInstance = new Logger(); - Options options; - smInstance->initialise( "undef", options ); - } - return( smInstance ); - } + static StringMap smCodes; + static IntMap smSyslogPriorities; private: - Logger(); - ~Logger(); + bool mInitialised; -public: - void initialise( const std::string &id, const Options &options ); - void terminate(); + std::string mId; + std::string mIdRoot; + std::string mIdArgs; + + Level mLevel; // Level that is currently in operation + Level mTermLevel; // Maximum level output via terminal + Level mDatabaseLevel; // Maximum level output via database + Level mFileLevel; // Maximum level output via file + Level mSyslogLevel; // Maximum level output via syslog + Level mEffectiveLevel; // Level optimised to take account of maxima + + bool mDbConnected; + MYSQL mDbConnection; + std::string mLogPath; + std::string mLogFile; + FILE *mLogFileFP; + + bool mHasTerm; + bool mFlush; private: - int limit( int level ) - { - if ( level > DEBUG9 ) - return( DEBUG9 ); - if ( level < NOLOG ) - return( NOLOG ); - return( level ); - } - - bool boolEnv( const std::string &name, bool defaultValue=false ); - int intEnv( const std::string &name, bool defaultValue=0 ); - std::string strEnv( const std::string &name, const std::string defaultValue="" ); - char *getTargettedEnv( const std::string &name ); - - void loadEnv(); + static void usrHandler( int sig ); public: - const std::string &id() const + friend void logInit( const char *name, const Options &options ); + friend void logTerm(); + + static Logger *fetch() + { + if ( !smInstance ) { - return( mId ); + smInstance = new Logger(); + Options options; + smInstance->initialise( "undef", options ); } - - const std::string &id( const std::string &id ); - - Level level() const - { - return( mLevel ); - } - Level level( Level=NOOPT ); - - bool debugOn() - { - return( mEffectiveLevel >= DEBUG1 ); - } - - Level termLevel( Level=NOOPT ); - Level databaseLevel( Level=NOOPT ); - Level fileLevel( Level=NOOPT ); - Level syslogLevel( Level=NOOPT ); + return( smInstance ); + } private: - void logFile( const std::string &logFile ); - void openFile(); - void closeFile(); - void openSyslog(); - void closeSyslog(); - void closeDatabase(); + Logger(); + ~Logger(); public: - void logPrint( bool hex, const char * const filepath, const int line, const int level, const char *fstring, ... ); + void initialise( const std::string &id, const Options &options ); + void terminate(); + +private: + int limit( int level ) + { + if ( level > DEBUG9 ) + return( DEBUG9 ); + if ( level < NOLOG ) + return( NOLOG ); + return( level ); + } + + bool boolEnv( const std::string &name, bool defaultValue=false ); + int intEnv( const std::string &name, bool defaultValue=0 ); + std::string strEnv( const std::string &name, const std::string defaultValue="" ); + char *getTargettedEnv( const std::string &name ); + + void loadEnv(); + +public: + const std::string &id() const + { + return( mId ); + } + + const std::string &id( const std::string &id ); + + Level level() const + { + return( mLevel ); + } + Level level( Level=NOOPT ); + + bool debugOn() + { + return( mEffectiveLevel >= DEBUG1 ); + } + + Level termLevel( Level=NOOPT ); + Level databaseLevel( Level=NOOPT ); + Level fileLevel( Level=NOOPT ); + Level syslogLevel( Level=NOOPT ); + +private: + void logFile( const std::string &logFile ); + void openFile(); + void closeFile(); + void openSyslog(); + void closeSyslog(); + void closeDatabase(); + +public: + void logPrint( bool hex, const char * const filepath, const int line, const int level, const char *fstring, ... ); }; void logInit( const char *name, const Logger::Options &options=Logger::Options() ); void logTerm(); inline const std::string &logId() { - return( Logger::fetch()->id() ); + return( Logger::fetch()->id() ); } inline Logger::Level logLevel() { - return( Logger::fetch()->level() ); + return( Logger::fetch()->level() ); } inline void logCapLevel( Logger::Level level ) { - Logger::fetch()->level( level ); + Logger::fetch()->level( level ); } inline Logger::Level logDebugging() { - return( Logger::fetch()->debugOn() ); + return( Logger::fetch()->debugOn() ); } #define logPrintf(logLevel,params...) {\ - if ( logLevel <= Logger::fetch()->level() )\ - Logger::fetch()->logPrint( false, __FILE__, __LINE__, logLevel, ##params );\ - } + if ( logLevel <= Logger::fetch()->level() )\ + Logger::fetch()->logPrint( false, __FILE__, __LINE__, logLevel, ##params );\ + } #define logHexdump(logLevel,data,len) {\ - if ( logLevel <= Logger::fetch()->level() )\ - Logger::fetch()->logPrint( true, __FILE__, __LINE__, logLevel, "%p (%d)", data, len );\ - } + if ( logLevel <= Logger::fetch()->level() )\ + Logger::fetch()->logPrint( true, __FILE__, __LINE__, logLevel, "%p (%d)", data, len );\ + } /* Debug compiled out */ #ifndef DBG_OFF @@ -228,19 +228,19 @@ inline Logger::Level logDebugging() #endif /* Standard debug calls */ -#define Info(params...) logPrintf(Logger::INFO,##params) +#define Info(params...) logPrintf(Logger::INFO,##params) #define Warning(params...) logPrintf(Logger::WARNING,##params) -#define Error(params...) logPrintf(Logger::ERROR,##params) -#define Fatal(params...) logPrintf(Logger::FATAL,##params) -#define Panic(params...) logPrintf(Logger::PANIC,##params) -#define Mark() Info("Mark/%s/%d",__FILE__,__LINE__) -#define Log() Info("Log") +#define Error(params...) logPrintf(Logger::ERROR,##params) +#define Fatal(params...) logPrintf(Logger::FATAL,##params) +#define Panic(params...) logPrintf(Logger::PANIC,##params) +#define Mark() Info("Mark/%s/%d",__FILE__,__LINE__) +#define Log() Info("Log") #ifdef __GNUC__ -#define Enter(level) logPrintf(level,("Entering %s",__PRETTY_FUNCTION__)) -#define Exit(level) logPrintf(level,("Exiting %s",__PRETTY_FUNCTION__)) +#define Enter(level) logPrintf(level,("Entering %s",__PRETTY_FUNCTION__)) +#define Exit(level) logPrintf(level,("Exiting %s",__PRETTY_FUNCTION__)) #else -#define Enter(level) -#define Exit(level) +#define Enter(level) +#define Exit(level) #endif #endif // ZM_LOGGER_H diff --git a/src/zm_mem_utils.h b/src/zm_mem_utils.h index 8ce1ceea1..351fa3ac8 100644 --- a/src/zm_mem_utils.h +++ b/src/zm_mem_utils.h @@ -24,138 +24,138 @@ #include "zm.h" inline void* zm_mallocaligned(unsigned int reqalignment, size_t reqsize) { - uint8_t* retptr; + uint8_t* retptr; #if HAVE_POSIX_MEMALIGN - if(posix_memalign((void**)&retptr,reqalignment,reqsize) != 0) - return NULL; - - return retptr; + if(posix_memalign((void**)&retptr,reqalignment,reqsize) != 0) + return NULL; + + return retptr; #else - uint8_t* alloc; - retptr = (uint8_t*)malloc(reqsize+reqalignment+sizeof(void*)); - - if(retptr == NULL) - return NULL; - - alloc = retptr + sizeof(void*); - - if(((long)alloc % reqalignment) != 0) - alloc = alloc + (reqalignment - ((long)alloc % reqalignment)); - - /* Store a pointer before to the start of the block, just before returned aligned memory */ - *(void**)(alloc - sizeof(void*)) = retptr; - - return alloc; + uint8_t* alloc; + retptr = (uint8_t*)malloc(reqsize+reqalignment+sizeof(void*)); + + if(retptr == NULL) + return NULL; + + alloc = retptr + sizeof(void*); + + if(((long)alloc % reqalignment) != 0) + alloc = alloc + (reqalignment - ((long)alloc % reqalignment)); + + /* Store a pointer before to the start of the block, just before returned aligned memory */ + *(void**)(alloc - sizeof(void*)) = retptr; + + return alloc; #endif } inline void zm_freealigned(void* ptr) { #if HAVE_POSIX_MEMALIGN - free(ptr); + free(ptr); #else - /* Start of block is stored before the block if it was allocated by zm_mallocaligned */ - free(*(void**)((uint8_t*)ptr - sizeof(void*))); + /* Start of block is stored before the block if it was allocated by zm_mallocaligned */ + free(*(void**)((uint8_t*)ptr - sizeof(void*))); #endif } inline char *mempbrk( register const char *s, const char *accept, size_t limit ) { - if ( limit <= 0 || !s || !accept || !*accept ) - return( 0 ); - - register unsigned int i,j; - size_t acc_len = strlen( accept ); - - for ( i = 0; i < limit; s++, i++ ) - { - for ( j = 0; j < acc_len; j++ ) - { - if ( *s == accept[j] ) - { - return( (char *)s ); - } - } - } + if ( limit <= 0 || !s || !accept || !*accept ) return( 0 ); + + register unsigned int i,j; + size_t acc_len = strlen( accept ); + + for ( i = 0; i < limit; s++, i++ ) + { + for ( j = 0; j < acc_len; j++ ) + { + if ( *s == accept[j] ) + { + return( (char *)s ); + } + } + } + return( 0 ); } inline char *memstr( register const char *s, const char *n, size_t limit ) { - if ( limit <= 0 || !s || !n ) - return( 0 ); - - if ( !*n ) - return( (char *)s ); - - register unsigned int i,j,k; - size_t n_len = strlen( n ); - - for ( i = 0; i < limit; i++, s++ ) - { - if ( *s != *n ) - continue; - j = 1; - k = 1; - while ( true ) - { - if ( k >= n_len ) - return( (char *)s ); - if ( s[j++] != n[k++] ) - break; - } - } + if ( limit <= 0 || !s || !n ) return( 0 ); + + if ( !*n ) + return( (char *)s ); + + register unsigned int i,j,k; + size_t n_len = strlen( n ); + + for ( i = 0; i < limit; i++, s++ ) + { + if ( *s != *n ) + continue; + j = 1; + k = 1; + while ( true ) + { + if ( k >= n_len ) + return( (char *)s ); + if ( s[j++] != n[k++] ) + break; + } + } + return( 0 ); } inline size_t memspn( register const char *s, const char *accept, size_t limit ) { - if ( limit <= 0 || !s || !accept || !*accept ) - return( 0 ); + if ( limit <= 0 || !s || !accept || !*accept ) + return( 0 ); - register unsigned int i,j; - size_t acc_len = strlen( accept ); + register unsigned int i,j; + size_t acc_len = strlen( accept ); - for ( i = 0; i < limit; s++, i++ ) + for ( i = 0; i < limit; s++, i++ ) + { + register bool found = false; + for ( j = 0; j < acc_len; j++ ) { - register bool found = false; - for ( j = 0; j < acc_len; j++ ) - { - if ( *s == accept[j] ) - { - found = true; - break; - } - } - if ( !found ) - { - return( i ); - } + if ( *s == accept[j] ) + { + found = true; + break; + } } - return( limit ); + if ( !found ) + { + return( i ); + } + } + return( limit ); } inline size_t memcspn( register const char *s, const char *reject, size_t limit ) { - if ( limit <= 0 || !s || !reject ) - return( 0 ); + if ( limit <= 0 || !s || !reject ) + return( 0 ); - if ( !*reject ) - return( limit ); - - register unsigned int i,j; - size_t rej_len = strlen( reject ); - - for ( i = 0; i < limit; s++, i++ ) - { - for ( j = 0; j < rej_len; j++ ) - { - if ( *s == reject[j] ) - { - return( i ); - } - } - } + if ( !*reject ) return( limit ); + + register unsigned int i,j; + size_t rej_len = strlen( reject ); + + for ( i = 0; i < limit; s++, i++ ) + { + for ( j = 0; j < rej_len; j++ ) + { + if ( *s == reject[j] ) + { + return( i ); + } + } + } + return( limit ); } #endif // ZM_MEM_UTILS_H diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index fc7008c14..0d945cc44 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -63,4534 +63,4339 @@ //============================================================================= std::vector split(const std::string &s, char delim) { - std::vector elems; - std::stringstream ss(s); - std::string item; - while(std::getline(ss, item, delim)) { - elems.push_back(trimSpaces(item)); - } - return elems; + std::vector elems; + std::stringstream ss(s); + std::string item; + while(std::getline(ss, item, delim)) { + elems.push_back(trimSpaces(item)); + } + return elems; } //============================================================================= Monitor::MonitorLink::MonitorLink( int p_id, const char *p_name ) : id( p_id ) { - strncpy( name, p_name, sizeof(name) ); + strncpy( name, p_name, sizeof(name) ); #if ZM_MEM_MAPPED - map_fd = -1; - snprintf( mem_file, sizeof(mem_file), "%s/zm.mmap.%d", config.path_map, id ); + map_fd = -1; + snprintf( mem_file, sizeof(mem_file), "%s/zm.mmap.%d", config.path_map, id ); #else // ZM_MEM_MAPPED - shm_id = 0; + shm_id = 0; #endif // ZM_MEM_MAPPED - mem_size = 0; - mem_ptr = 0; + mem_size = 0; + mem_ptr = 0; - last_event = 0; - last_state = IDLE; + last_event = 0; + last_state = IDLE; - last_connect_time = 0; - connected = false; + last_connect_time = 0; + connected = false; } Monitor::MonitorLink::~MonitorLink() { - disconnect(); + disconnect(); } bool Monitor::MonitorLink::connect() { - if ( !last_connect_time || (time( 0 ) - last_connect_time) > 60 ) { - last_connect_time = time( 0 ); + if ( !last_connect_time || (time( 0 ) - last_connect_time) > 60 ) { + last_connect_time = time( 0 ); - mem_size = sizeof(SharedData) + sizeof(TriggerData); + mem_size = sizeof(SharedData) + sizeof(TriggerData); - Debug( 1, "link.mem.size=%d", mem_size ); + Debug( 1, "link.mem.size=%d", mem_size ); #if ZM_MEM_MAPPED - map_fd = open( mem_file, O_RDWR, (mode_t)0600 ); - if ( map_fd < 0 ) { - Debug( 3, "Can't open linked memory map file %s: %s", mem_file, strerror(errno) ); - disconnect(); - return( false ); - } - while ( map_fd <= 2 ) { - int new_map_fd = dup(map_fd); - Warning( "Got one of the stdio fds for our mmap handle. map_fd was %d, new one is %d", map_fd, new_map_fd ); - close(map_fd); - map_fd = new_map_fd; - } + map_fd = open( mem_file, O_RDWR, (mode_t)0600 ); + if ( map_fd < 0 ) { + Debug( 3, "Can't open linked memory map file %s: %s", mem_file, strerror(errno) ); + disconnect(); + return( false ); + } + while ( map_fd <= 2 ) { + int new_map_fd = dup(map_fd); + Warning( "Got one of the stdio fds for our mmap handle. map_fd was %d, new one is %d", map_fd, new_map_fd ); + close(map_fd); + map_fd = new_map_fd; + } - struct stat map_stat; - if ( fstat( map_fd, &map_stat ) < 0 ) { - Error( "Can't stat linked memory map file %s: %s", mem_file, strerror(errno) ); - disconnect(); - return( false ); - } + struct stat map_stat; + if ( fstat( map_fd, &map_stat ) < 0 ) { + Error( "Can't stat linked memory map file %s: %s", mem_file, strerror(errno) ); + disconnect(); + return( false ); + } - if ( map_stat.st_size == 0 ) { - Error( "Linked memory map file %s is empty: %s", mem_file, strerror(errno) ); - disconnect(); - return( false ); - } else if ( map_stat.st_size < mem_size ) { - Error( "Got unexpected memory map file size %ld, expected %d", map_stat.st_size, mem_size ); - disconnect(); - return( false ); - } + if ( map_stat.st_size == 0 ) { + Error( "Linked memory map file %s is empty: %s", mem_file, strerror(errno) ); + disconnect(); + return( false ); + } else if ( map_stat.st_size < mem_size ) { + Error( "Got unexpected memory map file size %ld, expected %d", map_stat.st_size, mem_size ); + disconnect(); + return( false ); + } - mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0 ); - if ( mem_ptr == MAP_FAILED ) { - Error( "Can't map file %s (%d bytes) to memory: %s", mem_file, mem_size, strerror(errno) ); - disconnect(); - return( false ); - } + mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0 ); + if ( mem_ptr == MAP_FAILED ) { + Error( "Can't map file %s (%d bytes) to memory: %s", mem_file, mem_size, strerror(errno) ); + disconnect(); + return( false ); + } #else // ZM_MEM_MAPPED - shm_id = shmget( (config.shm_key&0xffff0000)|id, mem_size, 0700 ); - if ( shm_id < 0 ) { - Debug( 3, "Can't shmget link memory: %s", strerror(errno) ); - connected = false; - return( false ); - } - mem_ptr = (unsigned char *)shmat( shm_id, 0, 0 ); - if ( mem_ptr < 0 ) { - Debug( 3, "Can't shmat link memory: %s", strerror(errno) ); - connected = false; - return( false ); - } + shm_id = shmget( (config.shm_key&0xffff0000)|id, mem_size, 0700 ); + if ( shm_id < 0 ) { + Debug( 3, "Can't shmget link memory: %s", strerror(errno) ); + connected = false; + return( false ); + } + mem_ptr = (unsigned char *)shmat( shm_id, 0, 0 ); + if ( mem_ptr < 0 ) { + Debug( 3, "Can't shmat link memory: %s", strerror(errno) ); + connected = false; + return( false ); + } #endif // ZM_MEM_MAPPED - shared_data = (SharedData *)mem_ptr; - trigger_data = (TriggerData *)((char *)shared_data + sizeof(SharedData)); + shared_data = (SharedData *)mem_ptr; + trigger_data = (TriggerData *)((char *)shared_data + sizeof(SharedData)); - if ( !shared_data->valid ) { - Debug( 3, "Linked memory not initialised by capture daemon" ); - disconnect(); - return( false ); - } + if ( !shared_data->valid ) { + Debug( 3, "Linked memory not initialised by capture daemon" ); + disconnect(); + return( false ); + } - last_state = shared_data->state; - last_event = shared_data->last_event; - connected = true; + last_state = shared_data->state; + last_event = shared_data->last_event; + connected = true; - return( true ); - } - return( false ); + return( true ); + } + return( false ); } bool Monitor::MonitorLink::disconnect() { - if ( connected ) { - connected = false; + if ( connected ) { + connected = false; #if ZM_MEM_MAPPED - if ( mem_ptr > 0 ) { - msync( mem_ptr, mem_size, MS_ASYNC ); - munmap( mem_ptr, mem_size ); - } - if ( map_fd >= 0 ) - close( map_fd ); + if ( mem_ptr > 0 ) { + msync( mem_ptr, mem_size, MS_ASYNC ); + munmap( mem_ptr, mem_size ); + } + if ( map_fd >= 0 ) + close( map_fd ); - map_fd = -1; + map_fd = -1; #else // ZM_MEM_MAPPED - struct shmid_ds shm_data; - if ( shmctl( shm_id, IPC_STAT, &shm_data ) < 0 ) { - Debug( 3, "Can't shmctl: %s", strerror(errno) ); - return( false ); - } + struct shmid_ds shm_data; + if ( shmctl( shm_id, IPC_STAT, &shm_data ) < 0 ) { + Debug( 3, "Can't shmctl: %s", strerror(errno) ); + return( false ); + } - shm_id = 0; + shm_id = 0; - if ( shm_data.shm_nattch <= 1 ) { - if ( shmctl( shm_id, IPC_RMID, 0 ) < 0 ) { - Debug( 3, "Can't shmctl: %s", strerror(errno) ); - return( false ); - } - } + if ( shm_data.shm_nattch <= 1 ) { + if ( shmctl( shm_id, IPC_RMID, 0 ) < 0 ) { + Debug( 3, "Can't shmctl: %s", strerror(errno) ); + return( false ); + } + } - if ( shmdt( mem_ptr ) < 0 ) { - Debug( 3, "Can't shmdt: %s", strerror(errno) ); - return( false ); - } + if ( shmdt( mem_ptr ) < 0 ) { + Debug( 3, "Can't shmdt: %s", strerror(errno) ); + return( false ); + } #endif // ZM_MEM_MAPPED - mem_size = 0; - mem_ptr = 0; - } - return( true ); + mem_size = 0; + mem_ptr = 0; + } + return( true ); } bool Monitor::MonitorLink::isAlarmed() { - if ( !connected ) { - return( false ); - } - return( shared_data->state == ALARM ); + if ( !connected ) { + return( false ); + } + return( shared_data->state == ALARM ); } bool Monitor::MonitorLink::inAlarm() { - if ( !connected ) { - return( false ); - } - return( shared_data->state == ALARM || shared_data->state == ALERT ); + if ( !connected ) { + return( false ); + } + return( shared_data->state == ALARM || shared_data->state == ALERT ); } bool Monitor::MonitorLink::hasAlarmed() { - if ( shared_data->state == ALARM ) { - return( true ); - } else if ( shared_data->last_event != (unsigned int)last_event ) { - last_event = shared_data->last_event; - } - return( false ); + if ( shared_data->state == ALARM ) { + return( true ); + } else if ( shared_data->last_event != (unsigned int)last_event ) { + last_event = shared_data->last_event; + } + return( false ); } Monitor::Monitor( - int p_id, - const char *p_name, - const unsigned int p_server_id, - const unsigned int p_storage_id, - int p_function, - bool p_enabled, - const char *p_linked_monitors, - Camera *p_camera, - int p_orientation, - unsigned int p_deinterlacing, - int p_savejpegs, - int p_videowriter, - std::string p_encoderparams, - bool p_record_audio, - const char *p_event_prefix, - const char *p_label_format, - const Coord &p_label_coord, - int p_label_size, - int p_image_buffer_count, - int p_warmup_count, - int p_pre_event_count, - int p_post_event_count, - int p_stream_replay_buffer, - int p_alarm_frame_count, - int p_section_length, - int p_frame_skip, - int p_motion_frame_skip, - double p_analysis_fps, - unsigned int p_analysis_update_delay, - int p_capture_delay, - int p_alarm_capture_delay, - int p_fps_report_interval, - int p_ref_blend_perc, - int p_alarm_ref_blend_perc, - bool p_track_motion, - Rgb p_signal_check_colour, - bool p_embed_exif, - Purpose p_purpose, - int p_n_zones, - Zone *p_zones[] + int p_id, + const char *p_name, + const unsigned int p_server_id, + const unsigned int p_storage_id, + int p_function, + bool p_enabled, + const char *p_linked_monitors, + Camera *p_camera, + int p_orientation, + unsigned int p_deinterlacing, + int p_savejpegs, + int p_videowriter, + std::string p_encoderparams, + bool p_record_audio, + const char *p_event_prefix, + const char *p_label_format, + const Coord &p_label_coord, + int p_label_size, + int p_image_buffer_count, + int p_warmup_count, + int p_pre_event_count, + int p_post_event_count, + int p_stream_replay_buffer, + int p_alarm_frame_count, + int p_section_length, + int p_frame_skip, + int p_motion_frame_skip, + double p_analysis_fps, + unsigned int p_analysis_update_delay, + int p_capture_delay, + int p_alarm_capture_delay, + int p_fps_report_interval, + int p_ref_blend_perc, + int p_alarm_ref_blend_perc, + bool p_track_motion, + Rgb p_signal_check_colour, + bool p_embed_exif, + Purpose p_purpose, + int p_n_zones, + Zone *p_zones[] ) : id( p_id ), - server_id( p_server_id ), - storage_id( p_storage_id ), - function( (Function)p_function ), - enabled( p_enabled ), - width( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Height():p_camera->Width() ), - height( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ), - orientation( (Orientation)p_orientation ), - deinterlacing( p_deinterlacing ), - savejpegspref( p_savejpegs ), - videowriterpref( p_videowriter ), - encoderparams( p_encoderparams ), - record_audio( p_record_audio ), - label_coord( p_label_coord ), - label_size( p_label_size ), - image_buffer_count( p_image_buffer_count ), - warmup_count( p_warmup_count ), - pre_event_count( p_pre_event_count ), - post_event_count( p_post_event_count ), - stream_replay_buffer( p_stream_replay_buffer ), - section_length( p_section_length ), - frame_skip( p_frame_skip ), - motion_frame_skip( p_motion_frame_skip ), - analysis_fps( p_analysis_fps ), - analysis_update_delay( p_analysis_update_delay ), - capture_delay( p_capture_delay ), - alarm_capture_delay( p_alarm_capture_delay ), - alarm_frame_count( p_alarm_frame_count ), - fps_report_interval( p_fps_report_interval ), - ref_blend_perc( p_ref_blend_perc ), - alarm_ref_blend_perc( p_alarm_ref_blend_perc ), - track_motion( p_track_motion ), - signal_check_colour( p_signal_check_colour ), - embed_exif( p_embed_exif ), - delta_image( width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE ), - ref_image( width, height, p_camera->Colours(), p_camera->SubpixelOrder() ), - purpose( p_purpose ), - last_motion_score(0), - camera( p_camera ), - n_zones( p_n_zones ), - zones( p_zones ), - timestamps( 0 ), - images( 0 ), - privacy_bitmask( NULL ) + server_id( p_server_id ), + storage_id( p_storage_id ), + function( (Function)p_function ), + enabled( p_enabled ), + width( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Height():p_camera->Width() ), + height( (p_orientation==ROTATE_90||p_orientation==ROTATE_270)?p_camera->Width():p_camera->Height() ), + orientation( (Orientation)p_orientation ), + deinterlacing( p_deinterlacing ), + savejpegspref( p_savejpegs ), + videowriterpref( p_videowriter ), + encoderparams( p_encoderparams ), + record_audio( p_record_audio ), + label_coord( p_label_coord ), + label_size( p_label_size ), + image_buffer_count( p_image_buffer_count ), + warmup_count( p_warmup_count ), + pre_event_count( p_pre_event_count ), + post_event_count( p_post_event_count ), + stream_replay_buffer( p_stream_replay_buffer ), + section_length( p_section_length ), + frame_skip( p_frame_skip ), + motion_frame_skip( p_motion_frame_skip ), + analysis_fps( p_analysis_fps ), + analysis_update_delay( p_analysis_update_delay ), + capture_delay( p_capture_delay ), + alarm_capture_delay( p_alarm_capture_delay ), + alarm_frame_count( p_alarm_frame_count ), + fps_report_interval( p_fps_report_interval ), + ref_blend_perc( p_ref_blend_perc ), + alarm_ref_blend_perc( p_alarm_ref_blend_perc ), + track_motion( p_track_motion ), + signal_check_colour( p_signal_check_colour ), + embed_exif( p_embed_exif ), + delta_image( width, height, ZM_COLOUR_GRAY8, ZM_SUBPIX_ORDER_NONE ), + ref_image( width, height, p_camera->Colours(), p_camera->SubpixelOrder() ), + purpose( p_purpose ), + last_motion_score(0), + camera( p_camera ), + n_zones( p_n_zones ), + zones( p_zones ), + timestamps( 0 ), + images( 0 ), + privacy_bitmask( NULL ) { - strncpy( name, p_name, sizeof(name)-1 ); + strncpy( name, p_name, sizeof(name)-1 ); - strncpy( event_prefix, p_event_prefix, sizeof(event_prefix)-1 ); - strncpy( label_format, p_label_format, sizeof(label_format)-1 ); + strncpy( event_prefix, p_event_prefix, sizeof(event_prefix)-1 ); + strncpy( label_format, p_label_format, sizeof(label_format)-1 ); - // Change \n to actual line feeds - char *token_ptr = label_format; - const char *token_string = "\n"; - while( ( token_ptr = strstr( token_ptr, token_string ) ) ) - { - if ( *(token_ptr+1) ) - { - *token_ptr = '\n'; - token_ptr++; - strcpy( token_ptr, token_ptr+1 ); - } - else - { - *token_ptr = '\0'; - break; - } - } + // Change \n to actual line feeds + char *token_ptr = label_format; + const char *token_string = "\n"; + while( ( token_ptr = strstr( token_ptr, token_string ) ) ) + { + if ( *(token_ptr+1) ) + { + *token_ptr = '\n'; + token_ptr++; + strcpy( token_ptr, token_ptr+1 ); + } + else + { + *token_ptr = '\0'; + break; + } + } - /* Parse encoder parameters */ - ParseEncoderParameters(encoderparams.c_str(), &encoderparamsvec); + /* Parse encoder parameters */ + ParseEncoderParameters(encoderparams.c_str(), &encoderparamsvec); - fps = 0.0; - event_count = 0; - image_count = 0; - ready_count = warmup_count; - first_alarm_count = 0; - last_alarm_count = 0; - state = IDLE; + fps = 0.0; + event_count = 0; + image_count = 0; + ready_count = warmup_count; + first_alarm_count = 0; + last_alarm_count = 0; + state = IDLE; - if ( alarm_frame_count < 1 ) - alarm_frame_count = 1; - else if ( alarm_frame_count > MAX_PRE_ALARM_FRAMES ) - alarm_frame_count = MAX_PRE_ALARM_FRAMES; + if ( alarm_frame_count < 1 ) + alarm_frame_count = 1; + else if ( alarm_frame_count > MAX_PRE_ALARM_FRAMES ) + alarm_frame_count = MAX_PRE_ALARM_FRAMES; - auto_resume_time = 0; + auto_resume_time = 0; - if ( strcmp( config.event_close_mode, "time" ) == 0 ) - event_close_mode = CLOSE_TIME; - else if ( strcmp( config.event_close_mode, "alarm" ) == 0 ) - event_close_mode = CLOSE_ALARM; - else - event_close_mode = CLOSE_IDLE; + if ( strcmp( config.event_close_mode, "time" ) == 0 ) + event_close_mode = CLOSE_TIME; + else if ( strcmp( config.event_close_mode, "alarm" ) == 0 ) + event_close_mode = CLOSE_ALARM; + else + event_close_mode = CLOSE_IDLE; - Debug( 1, "monitor purpose=%d", purpose ); + Debug( 1, "monitor purpose=%d", purpose ); - mem_size = sizeof(SharedData) - + sizeof(TriggerData) - + sizeof(VideoStoreData) //Information to pass back to the capture process - + (image_buffer_count*sizeof(struct timeval)) - + (image_buffer_count*camera->ImageSize()) - + 64; /* Padding used to permit aligning the images buffer to 16 byte boundary */ + mem_size = sizeof(SharedData) + + sizeof(TriggerData) + + sizeof(VideoStoreData) //Information to pass back to the capture process + + (image_buffer_count*sizeof(struct timeval)) + + (image_buffer_count*camera->ImageSize()) + + 64; /* Padding used to permit aligning the images buffer to 16 byte boundary */ - Debug( 1, "mem.size=%d", mem_size ); - mem_ptr = NULL; + Debug( 1, "mem.size=%d", mem_size ); + mem_ptr = NULL; - if ( purpose == CAPTURE ) { - this->connect(); - if ( ! mem_ptr ) exit(-1); - memset( mem_ptr, 0, mem_size ); - shared_data->size = sizeof(SharedData); - shared_data->active = enabled; - shared_data->signal = false; - shared_data->state = IDLE; - shared_data->last_write_index = image_buffer_count; - shared_data->last_read_index = image_buffer_count; - shared_data->last_write_time = 0; - shared_data->last_event = 0; - shared_data->action = (Action)0; - shared_data->brightness = -1; - shared_data->hue = -1; - shared_data->colour = -1; - shared_data->contrast = -1; - shared_data->alarm_x = -1; - shared_data->alarm_y = -1; - shared_data->format = camera->SubpixelOrder(); - shared_data->imagesize = camera->ImageSize(); - trigger_data->size = sizeof(TriggerData); - trigger_data->trigger_state = TRIGGER_CANCEL; - trigger_data->trigger_score = 0; - trigger_data->trigger_cause[0] = 0; - trigger_data->trigger_text[0] = 0; - trigger_data->trigger_showtext[0] = 0; - shared_data->valid = true; - video_store_data->recording = false; - snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "nothing"); - video_store_data->size = sizeof(VideoStoreData); - //video_store_data->frameNumber = 0; - } else if ( purpose == ANALYSIS ) { - this->connect(); - if ( ! mem_ptr ) exit(-1); - shared_data->state = IDLE; - shared_data->last_read_time = 0; - shared_data->alarm_x = -1; - shared_data->alarm_y = -1; - } + if ( purpose == CAPTURE ) { + this->connect(); + if ( ! mem_ptr ) exit(-1); + memset( mem_ptr, 0, mem_size ); + shared_data->size = sizeof(SharedData); + shared_data->active = enabled; + shared_data->signal = false; + shared_data->state = IDLE; + shared_data->last_write_index = image_buffer_count; + shared_data->last_read_index = image_buffer_count; + shared_data->last_write_time = 0; + shared_data->last_event = 0; + shared_data->action = (Action)0; + shared_data->brightness = -1; + shared_data->hue = -1; + shared_data->colour = -1; + shared_data->contrast = -1; + shared_data->alarm_x = -1; + shared_data->alarm_y = -1; + shared_data->format = camera->SubpixelOrder(); + shared_data->imagesize = camera->ImageSize(); + trigger_data->size = sizeof(TriggerData); + trigger_data->trigger_state = TRIGGER_CANCEL; + trigger_data->trigger_score = 0; + trigger_data->trigger_cause[0] = 0; + trigger_data->trigger_text[0] = 0; + trigger_data->trigger_showtext[0] = 0; + shared_data->valid = true; + video_store_data->recording = false; + snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "nothing"); + video_store_data->size = sizeof(VideoStoreData); + //video_store_data->frameNumber = 0; + } else if ( purpose == ANALYSIS ) { + this->connect(); + if ( ! mem_ptr ) exit(-1); + shared_data->state = IDLE; + shared_data->last_read_time = 0; + shared_data->alarm_x = -1; + shared_data->alarm_y = -1; + } - if ( ( ! mem_ptr ) || ! shared_data->valid ) { - if ( purpose != QUERY ) { - Error( "Shared data not initialised by capture daemon for monitor %s", name ); - exit( -1 ); - } - } + if ( ( ! mem_ptr ) || ! shared_data->valid ) { + if ( purpose != QUERY ) { + Error( "Shared data not initialised by capture daemon for monitor %s", name ); + exit( -1 ); + } + } - // Will this not happen every time a monitor is instantiated? Seems like all the calls to the Monitor constructor pass a zero for n_zones, then load zones after.. - // In my storage areas branch, I took this out.. and didn't notice any problems. - if ( !n_zones ) { - Debug( 1, "Monitor %s has no zones, adding one.", name ); - n_zones = 1; - zones = new Zone *[1]; - Coord coords[4] = { Coord( 0, 0 ), Coord( width-1, 0 ), Coord( width-1, height-1 ), Coord( 0, height-1 ) }; - zones[0] = new Zone( this, 0, "All", Zone::ACTIVE, Polygon( sizeof(coords)/sizeof(*coords), coords ), RGB_RED, Zone::BLOBS ); - } - start_time = last_fps_time = time( 0 ); + // Will this not happen every time a monitor is instantiated? Seems like all the calls to the Monitor constructor pass a zero for n_zones, then load zones after.. + // In my storage areas branch, I took this out.. and didn't notice any problems. + if ( !n_zones ) { + Debug( 1, "Monitor %s has no zones, adding one.", name ); + n_zones = 1; + zones = new Zone *[1]; + Coord coords[4] = { Coord( 0, 0 ), Coord( width-1, 0 ), Coord( width-1, height-1 ), Coord( 0, height-1 ) }; + zones[0] = new Zone( this, 0, "All", Zone::ACTIVE, Polygon( sizeof(coords)/sizeof(*coords), coords ), RGB_RED, Zone::BLOBS ); + } + start_time = last_fps_time = time( 0 ); - event = 0; + event = 0; - Debug( 1, "Monitor %s has function %d", name, function ); - Debug( 1, "Monitor %s LBF = '%s', LBX = %d, LBY = %d, LBS = %d", name, label_format, label_coord.X(), label_coord.Y(), label_size ); - Debug( 1, "Monitor %s IBC = %d, WUC = %d, pEC = %d, PEC = %d, EAF = %d, FRI = %d, RBP = %d, ARBP = %d, FM = %d", name, image_buffer_count, warmup_count, pre_event_count, post_event_count, alarm_frame_count, fps_report_interval, ref_blend_perc, alarm_ref_blend_perc, track_motion ); + Debug( 1, "Monitor %s has function %d", name, function ); + Debug( 1, "Monitor %s LBF = '%s', LBX = %d, LBY = %d, LBS = %d", name, label_format, label_coord.X(), label_coord.Y(), label_size ); + Debug( 1, "Monitor %s IBC = %d, WUC = %d, pEC = %d, PEC = %d, EAF = %d, FRI = %d, RBP = %d, ARBP = %d, FM = %d", name, image_buffer_count, warmup_count, pre_event_count, post_event_count, alarm_frame_count, fps_report_interval, ref_blend_perc, alarm_ref_blend_perc, track_motion ); - storage = new Storage( storage_id ); - Debug(1, "Storage path: %s", storage->Path() ); + storage = new Storage( storage_id ); + Debug(1, "Storage path: %s", storage->Path() ); - if ( purpose == ANALYSIS ) { - static char path[PATH_MAX]; + if ( purpose == ANALYSIS ) { + static char path[PATH_MAX]; - strncpy( path, storage->Path(), sizeof(path) ); + strncpy( path, storage->Path(), sizeof(path) ); - struct stat statbuf; - errno = 0; - stat( path, &statbuf ); - if ( errno == ENOENT || errno == ENOTDIR ) { - if ( mkdir( path, 0755 ) ) { - Error( "Can't make %s: %s", path, strerror(errno)); - } - } + struct stat statbuf; + errno = 0; + stat( path, &statbuf ); + if ( errno == ENOENT || errno == ENOTDIR ) { + if ( mkdir( path, 0755 ) ) { + Error( "Can't make %s: %s", path, strerror(errno)); + } + } - snprintf( path, sizeof(path), "%s/%d", storage->Path(), id ); + snprintf( path, sizeof(path), "%s/%d", storage->Path(), id ); - errno = 0; - stat( path, &statbuf ); - if ( errno == ENOENT || errno == ENOTDIR ) { - if ( mkdir( path, 0755 ) ) { - Error( "Can't make %s: %s", path, strerror(errno)); - } - char temp_path[PATH_MAX]; - snprintf( temp_path, sizeof(temp_path), "%d", id ); - if ( chdir( storage->Path() ) < 0 ) - Fatal( "Can't change directory to '%s': %s", storage->Path(), strerror(errno) ); - if ( symlink( temp_path, name ) < 0 ) - Fatal( "Can't symlink '%s' to '%s': %s", temp_path, name, strerror(errno) ); - if ( chdir( ".." ) < 0 ) - Fatal( "Can't change to parent directory: %s", strerror(errno) ); - } + errno = 0; + stat( path, &statbuf ); + if ( errno == ENOENT || errno == ENOTDIR ) { + if ( mkdir( path, 0755 ) ) { + Error( "Can't make %s: %s", path, strerror(errno)); + } + char temp_path[PATH_MAX]; + snprintf( temp_path, sizeof(temp_path), "%d", id ); + if ( chdir( storage->Path() ) < 0 ) + Fatal( "Can't change directory to '%s': %s", storage->Path(), strerror(errno) ); + if ( symlink( temp_path, name ) < 0 ) + Fatal( "Can't symlink '%s' to '%s': %s", temp_path, name, strerror(errno) ); + if ( chdir( ".." ) < 0 ) + Fatal( "Can't change to parent directory: %s", strerror(errno) ); + } - while( shared_data->last_write_index == (unsigned int)image_buffer_count - && shared_data->last_write_time == 0) { - Warning( "Waiting for capture daemon" ); - sleep( 1 ); - } - ref_image.Assign( width, height, camera->Colours(), camera->SubpixelOrder(), image_buffer[shared_data->last_write_index].image->Buffer(), camera->ImageSize()); + while( shared_data->last_write_index == (unsigned int)image_buffer_count + && shared_data->last_write_time == 0) { + Warning( "Waiting for capture daemon" ); + sleep( 1 ); + } + ref_image.Assign( width, height, camera->Colours(), camera->SubpixelOrder(), image_buffer[shared_data->last_write_index].image->Buffer(), camera->ImageSize()); - n_linked_monitors = 0; - linked_monitors = 0; + n_linked_monitors = 0; + linked_monitors = 0; - adaptive_skip = true; + adaptive_skip = true; - ReloadLinkedMonitors( p_linked_monitors ); - } + ReloadLinkedMonitors( p_linked_monitors ); + } } bool Monitor::connect() { #if ZM_MEM_MAPPED - snprintf( mem_file, sizeof(mem_file), "%s/zm.mmap.%d", config.path_map, id ); - map_fd = open( mem_file, O_RDWR|O_CREAT, (mode_t)0600 ); - if ( map_fd < 0 ) - Fatal( "Can't open memory map file %s, probably not enough space free: %s", mem_file, strerror(errno) ); + snprintf( mem_file, sizeof(mem_file), "%s/zm.mmap.%d", config.path_map, id ); + map_fd = open( mem_file, O_RDWR|O_CREAT, (mode_t)0600 ); + if ( map_fd < 0 ) + Fatal( "Can't open memory map file %s, probably not enough space free: %s", mem_file, strerror(errno) ); - struct stat map_stat; - if ( fstat( map_fd, &map_stat ) < 0 ) - Fatal( "Can't stat memory map file %s: %s, is the zmc process for this monitor running?", mem_file, strerror(errno) ); - if ( map_stat.st_size != mem_size && purpose == CAPTURE ) { - // Allocate the size - if ( ftruncate( map_fd, mem_size ) < 0 ) { - Fatal( "Can't extend memory map file %s to %d bytes: %s", mem_file, mem_size, strerror(errno) ); - } - } else if ( map_stat.st_size == 0 ) { - Error( "Got empty memory map file size %ld, is the zmc process for this monitor running?", map_stat.st_size, mem_size ); - return false; - } else if ( map_stat.st_size != mem_size ) { - Error( "Got unexpected memory map file size %ld, expected %d", map_stat.st_size, mem_size ); - return false; - } else { + struct stat map_stat; + if ( fstat( map_fd, &map_stat ) < 0 ) + Fatal( "Can't stat memory map file %s: %s, is the zmc process for this monitor running?", mem_file, strerror(errno) ); + if ( map_stat.st_size != mem_size && purpose == CAPTURE ) { + // Allocate the size + if ( ftruncate( map_fd, mem_size ) < 0 ) { + Fatal( "Can't extend memory map file %s to %d bytes: %s", mem_file, mem_size, strerror(errno) ); + } + } else if ( map_stat.st_size == 0 ) { + Error( "Got empty memory map file size %ld, is the zmc process for this monitor running?", map_stat.st_size, mem_size ); + return false; + } else if ( map_stat.st_size != mem_size ) { + Error( "Got unexpected memory map file size %ld, expected %d", map_stat.st_size, mem_size ); + return false; + } else { #ifdef MAP_LOCKED - mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0 ); - if ( mem_ptr == MAP_FAILED ) { - if ( errno == EAGAIN ) { - Debug( 1, "Unable to map file %s (%d bytes) to locked memory, trying unlocked", mem_file, mem_size ); + mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED, map_fd, 0 ); + if ( mem_ptr == MAP_FAILED ) { + if ( errno == EAGAIN ) { + Debug( 1, "Unable to map file %s (%d bytes) to locked memory, trying unlocked", mem_file, mem_size ); #endif - mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0 ); - Debug( 1, "Mapped file %s (%d bytes) to locked memory, unlocked", mem_file, mem_size ); + mem_ptr = (unsigned char *)mmap( NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, 0 ); + Debug( 1, "Mapped file %s (%d bytes) to locked memory, unlocked", mem_file, mem_size ); #ifdef MAP_LOCKED - } - } + } + } #endif - if ( mem_ptr == MAP_FAILED ) - Fatal( "Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno ); - } + if ( mem_ptr == MAP_FAILED ) + Fatal( "Can't map file %s (%d bytes) to memory: %s(%d)", mem_file, mem_size, strerror(errno), errno ); + } #else // ZM_MEM_MAPPED - shm_id = shmget( (config.shm_key&0xffff0000)|id, mem_size, IPC_CREAT|0700 ); - if ( shm_id < 0 ) { - Error( "Can't shmget, probably not enough shared memory space free: %s", strerror(errno)); - exit( -1 ); - } - mem_ptr = (unsigned char *)shmat( shm_id, 0, 0 ); - if ( mem_ptr < 0 ) { - Error( "Can't shmat: %s", strerror(errno)); - exit( -1 ); - } + shm_id = shmget( (config.shm_key&0xffff0000)|id, mem_size, IPC_CREAT|0700 ); + if ( shm_id < 0 ) { + Error( "Can't shmget, probably not enough shared memory space free: %s", strerror(errno)); + exit( -1 ); + } + mem_ptr = (unsigned char *)shmat( shm_id, 0, 0 ); + if ( mem_ptr < 0 ) { + Error( "Can't shmat: %s", strerror(errno)); + exit( -1 ); + } #endif // ZM_MEM_MAPPED - shared_data = (SharedData *)mem_ptr; - trigger_data = (TriggerData *)((char *)shared_data + sizeof(SharedData)); - video_store_data = (VideoStoreData *)((char *)trigger_data + sizeof(TriggerData)); - struct timeval *shared_timestamps = (struct timeval *)((char *)video_store_data + sizeof(VideoStoreData)); - unsigned char *shared_images = (unsigned char *)((char *)shared_timestamps + (image_buffer_count*sizeof(struct timeval))); - - if(((unsigned long)shared_images % 16) != 0) { - /* Align images buffer to nearest 16 byte boundary */ - Debug(3,"Aligning shared memory images to the next 16 byte boundary"); - shared_images = (uint8_t*)((unsigned long)shared_images + (16 - ((unsigned long)shared_images % 16))); - } - image_buffer = new Snapshot[image_buffer_count]; - for ( int i = 0; i < image_buffer_count; i++ ) { - image_buffer[i].timestamp = &(shared_timestamps[i]); - image_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder(), &(shared_images[i*camera->ImageSize()]) ); - image_buffer[i].image->HoldBuffer(true); /* Don't release the internal buffer or replace it with another */ - } - if ( (deinterlacing & 0xff) == 4) { - /* Four field motion adaptive deinterlacing in use */ - /* Allocate a buffer for the next image */ - next_buffer.image = new Image( width, height, camera->Colours(), camera->SubpixelOrder()); - next_buffer.timestamp = new struct timeval; - } + shared_data = (SharedData *)mem_ptr; + trigger_data = (TriggerData *)((char *)shared_data + sizeof(SharedData)); + video_store_data = (VideoStoreData *)((char *)trigger_data + sizeof(TriggerData)); + struct timeval *shared_timestamps = (struct timeval *)((char *)video_store_data + sizeof(VideoStoreData)); + unsigned char *shared_images = (unsigned char *)((char *)shared_timestamps + (image_buffer_count*sizeof(struct timeval))); + + if(((unsigned long)shared_images % 16) != 0) { + /* Align images buffer to nearest 16 byte boundary */ + Debug(3,"Aligning shared memory images to the next 16 byte boundary"); + shared_images = (uint8_t*)((unsigned long)shared_images + (16 - ((unsigned long)shared_images % 16))); + } + image_buffer = new Snapshot[image_buffer_count]; + for ( int i = 0; i < image_buffer_count; i++ ) { + image_buffer[i].timestamp = &(shared_timestamps[i]); + image_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder(), &(shared_images[i*camera->ImageSize()]) ); + image_buffer[i].image->HoldBuffer(true); /* Don't release the internal buffer or replace it with another */ + } + if ( (deinterlacing & 0xff) == 4) { + /* Four field motion adaptive deinterlacing in use */ + /* Allocate a buffer for the next image */ + next_buffer.image = new Image( width, height, camera->Colours(), camera->SubpixelOrder()); + next_buffer.timestamp = new struct timeval; + } - if ( ( purpose == ANALYSIS ) && analysis_fps ) { - // Size of pre event buffer must be greater than pre_event_count - // if alarm_frame_count > 1, because in this case the buffer contains - // alarmed images that must be discarded when event is created - pre_event_buffer_count = pre_event_count + alarm_frame_count - 1; - pre_event_buffer = new Snapshot[pre_event_buffer_count]; - for ( int i = 0; i < pre_event_buffer_count; i++ ) { - pre_event_buffer[i].timestamp = new struct timeval; - pre_event_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder()); - } - } + if ( ( purpose == ANALYSIS ) && analysis_fps ) { + // Size of pre event buffer must be greater than pre_event_count + // if alarm_frame_count > 1, because in this case the buffer contains + // alarmed images that must be discarded when event is created + pre_event_buffer_count = pre_event_count + alarm_frame_count - 1; + pre_event_buffer = new Snapshot[pre_event_buffer_count]; + for ( int i = 0; i < pre_event_buffer_count; i++ ) { + pre_event_buffer[i].timestamp = new struct timeval; + pre_event_buffer[i].image = new Image( width, height, camera->Colours(), camera->SubpixelOrder()); + } + } - return true; + return true; } Monitor::~Monitor() { - if ( timestamps ) { - delete[] timestamps; - timestamps = 0; - } - if ( images ) { - delete[] images; - images = 0; - } - if ( privacy_bitmask ) { - delete[] privacy_bitmask; - privacy_bitmask = NULL; - } - if ( mem_ptr ) { - if ( event ) - Info( "%s: %03d - Closing event %d, shutting down", name, image_count, event->Id() ); - closeEvent(); + if ( timestamps ) { + delete[] timestamps; + timestamps = 0; + } + if ( images ) { + delete[] images; + images = 0; + } + if ( privacy_bitmask ) { + delete[] privacy_bitmask; + privacy_bitmask = NULL; + } + if ( mem_ptr ) { + if ( event ) + Info( "%s: %03d - Closing event %d, shutting down", name, image_count, event->Id() ); + closeEvent(); - if ( (deinterlacing & 0xff) == 4) - { - delete next_buffer.image; - delete next_buffer.timestamp; - } - for ( int i = 0; i < image_buffer_count; i++ ) - { - delete image_buffer[i].image; - } - delete[] image_buffer; - } // end if mem_ptr + if ( (deinterlacing & 0xff) == 4) + { + delete next_buffer.image; + delete next_buffer.timestamp; + } + for ( int i = 0; i < image_buffer_count; i++ ) + { + delete image_buffer[i].image; + } + delete[] image_buffer; + } // end if mem_ptr - for ( int i = 0; i < n_zones; i++ ) - { - delete zones[i]; - } - delete[] zones; + for ( int i = 0; i < n_zones; i++ ) + { + delete zones[i]; + } + delete[] zones; - delete camera; - delete storage; + delete camera; + delete storage; - if ( mem_ptr ) { - if ( purpose == ANALYSIS ) - { - shared_data->state = state = IDLE; - shared_data->last_read_index = image_buffer_count; - shared_data->last_read_time = 0; + if ( mem_ptr ) { + if ( purpose == ANALYSIS ) + { + shared_data->state = state = IDLE; + shared_data->last_read_index = image_buffer_count; + shared_data->last_read_time = 0; - if ( analysis_fps ) - { - for ( int i = 0; i < pre_event_buffer_count; i++ ) - { - delete pre_event_buffer[i].image; - delete pre_event_buffer[i].timestamp; - } - delete[] pre_event_buffer; - } - } - else if ( purpose == CAPTURE ) - { - shared_data->valid = false; - memset( mem_ptr, 0, mem_size ); - } + if ( analysis_fps ) + { + for ( int i = 0; i < pre_event_buffer_count; i++ ) + { + delete pre_event_buffer[i].image; + delete pre_event_buffer[i].timestamp; + } + delete[] pre_event_buffer; + } + } + else if ( purpose == CAPTURE ) + { + shared_data->valid = false; + memset( mem_ptr, 0, mem_size ); + } #if ZM_MEM_MAPPED - if ( msync( mem_ptr, mem_size, MS_SYNC ) < 0 ) - Error( "Can't msync: %s", strerror(errno) ); - if ( munmap( mem_ptr, mem_size ) < 0 ) - Fatal( "Can't munmap: %s", strerror(errno) ); - close( map_fd ); + if ( msync( mem_ptr, mem_size, MS_SYNC ) < 0 ) + Error( "Can't msync: %s", strerror(errno) ); + if ( munmap( mem_ptr, mem_size ) < 0 ) + Fatal( "Can't munmap: %s", strerror(errno) ); + close( map_fd ); #else // ZM_MEM_MAPPED - struct shmid_ds shm_data; - if ( shmctl( shm_id, IPC_STAT, &shm_data ) < 0 ) { - Error( "Can't shmctl: %s", strerror(errno) ); - exit( -1 ); - } - if ( shm_data.shm_nattch <= 1 ) { - if ( shmctl( shm_id, IPC_RMID, 0 ) < 0 ) { - Error( "Can't shmctl: %s", strerror(errno) ); - exit( -1 ); - } - } + struct shmid_ds shm_data; + if ( shmctl( shm_id, IPC_STAT, &shm_data ) < 0 ) { + Error( "Can't shmctl: %s", strerror(errno) ); + exit( -1 ); + } + if ( shm_data.shm_nattch <= 1 ) { + if ( shmctl( shm_id, IPC_RMID, 0 ) < 0 ) { + Error( "Can't shmctl: %s", strerror(errno) ); + exit( -1 ); + } + } #endif // ZM_MEM_MAPPED - } // end if mem_ptr + } // end if mem_ptr } void Monitor::AddZones( int p_n_zones, Zone *p_zones[] ) { - for ( int i = 0; i < n_zones; i++ ) - delete zones[i]; - delete[] zones; - n_zones = p_n_zones; - zones = p_zones; + for ( int i = 0; i < n_zones; i++ ) + delete zones[i]; + delete[] zones; + n_zones = p_n_zones; + zones = p_zones; } void Monitor::AddPrivacyBitmask( Zone *p_zones[] ) { - if ( privacy_bitmask ) - delete[] privacy_bitmask; - privacy_bitmask = NULL; - Image *privacy_image = NULL; + if ( privacy_bitmask ) + delete[] privacy_bitmask; + privacy_bitmask = NULL; + Image *privacy_image = NULL; - for ( int i = 0; i < n_zones; i++ ) - { - if ( p_zones[i]->IsPrivacy() ) - { - if ( !privacy_image ) - { - privacy_image = new Image( width, height, 1, ZM_SUBPIX_ORDER_NONE); - privacy_image->Clear(); - } - privacy_image->Fill( 0xff, p_zones[i]->GetPolygon() ); - privacy_image->Outline( 0xff, p_zones[i]->GetPolygon() ); - } - } // end foreach zone - if ( privacy_image ) - privacy_bitmask = privacy_image->Buffer(); + for ( int i = 0; i < n_zones; i++ ) + { + if ( p_zones[i]->IsPrivacy() ) + { + if ( !privacy_image ) + { + privacy_image = new Image( width, height, 1, ZM_SUBPIX_ORDER_NONE); + privacy_image->Clear(); + } + privacy_image->Fill( 0xff, p_zones[i]->GetPolygon() ); + privacy_image->Outline( 0xff, p_zones[i]->GetPolygon() ); + } + } // end foreach zone + if ( privacy_image ) + privacy_bitmask = privacy_image->Buffer(); } Monitor::State Monitor::GetState() const { - return( (State)shared_data->state ); + return( (State)shared_data->state ); } int Monitor::GetImage( int index, int scale ) { - if ( index < 0 || index > image_buffer_count ) - { - index = shared_data->last_write_index; - } + if ( index < 0 || index > image_buffer_count ) + { + index = shared_data->last_write_index; + } - if ( index != image_buffer_count ) - { - Image *image; - // If we are going to be modifying the snapshot before writing, then we need to copy it - if ( ( scale != ZM_SCALE_BASE ) || ( !config.timestamp_on_capture ) ) { - Snapshot *snap = &image_buffer[index]; - Image *snap_image = snap->image; + if ( index != image_buffer_count ) + { + Image *image; + // If we are going to be modifying the snapshot before writing, then we need to copy it + if ( ( scale != ZM_SCALE_BASE ) || ( !config.timestamp_on_capture ) ) { + Snapshot *snap = &image_buffer[index]; + Image *snap_image = snap->image; - alarm_image.Assign( *snap_image ); + alarm_image.Assign( *snap_image ); - //write_image.Assign( *snap_image ); + //write_image.Assign( *snap_image ); - if ( scale != ZM_SCALE_BASE ) { - alarm_image.Scale( scale ); - } + if ( scale != ZM_SCALE_BASE ) { + alarm_image.Scale( scale ); + } - if ( !config.timestamp_on_capture ) { - TimestampImage( &alarm_image, snap->timestamp ); - } - image = &alarm_image; - } else { - image = image_buffer[index].image; - } + if ( !config.timestamp_on_capture ) { + TimestampImage( &alarm_image, snap->timestamp ); + } + image = &alarm_image; + } else { + image = image_buffer[index].image; + } - static char filename[PATH_MAX]; - snprintf( filename, sizeof(filename), "Monitor%d.jpg", id ); - image->WriteJpeg( filename ); - } - else - { - Error( "Unable to generate image, no images in buffer" ); - } - return( 0 ); + static char filename[PATH_MAX]; + snprintf( filename, sizeof(filename), "Monitor%d.jpg", id ); + image->WriteJpeg( filename ); + } + else + { + Error( "Unable to generate image, no images in buffer" ); + } + return( 0 ); } struct timeval Monitor::GetTimestamp( int index ) const { - if ( index < 0 || index > image_buffer_count ) - { - index = shared_data->last_write_index; - } + if ( index < 0 || index > image_buffer_count ) + { + index = shared_data->last_write_index; + } - if ( index != image_buffer_count ) - { - Snapshot *snap = &image_buffer[index]; + if ( index != image_buffer_count ) + { + Snapshot *snap = &image_buffer[index]; - return( *(snap->timestamp) ); - } - else - { - static struct timeval null_tv = { 0, 0 }; + return( *(snap->timestamp) ); + } + else + { + static struct timeval null_tv = { 0, 0 }; - return( null_tv ); - } + return( null_tv ); + } } unsigned int Monitor::GetLastReadIndex() const { - return( shared_data->last_read_index!=(unsigned int)image_buffer_count?shared_data->last_read_index:-1 ); + return( shared_data->last_read_index!=(unsigned int)image_buffer_count?shared_data->last_read_index:-1 ); } unsigned int Monitor::GetLastWriteIndex() const { - return( shared_data->last_write_index!=(unsigned int)image_buffer_count?shared_data->last_write_index:-1 ); + return( shared_data->last_write_index!=(unsigned int)image_buffer_count?shared_data->last_write_index:-1 ); } unsigned int Monitor::GetLastEvent() const { - return( shared_data->last_event ); + return( shared_data->last_event ); } double Monitor::GetFPS() const { - int index1 = shared_data->last_write_index; - if ( index1 == image_buffer_count ) - { - return( 0.0 ); - } - Snapshot *snap1 = &image_buffer[index1]; - if ( !snap1->timestamp || !snap1->timestamp->tv_sec ) - { - return( 0.0 ); - } - struct timeval time1 = *snap1->timestamp; + int index1 = shared_data->last_write_index; + if ( index1 == image_buffer_count ) + { + return( 0.0 ); + } + Snapshot *snap1 = &image_buffer[index1]; + if ( !snap1->timestamp || !snap1->timestamp->tv_sec ) + { + return( 0.0 ); + } + struct timeval time1 = *snap1->timestamp; - int image_count = image_buffer_count; - int index2 = (index1+1)%image_buffer_count; - if ( index2 == image_buffer_count ) - { - return( 0.0 ); - } - Snapshot *snap2 = &image_buffer[index2]; - while ( !snap2->timestamp || !snap2->timestamp->tv_sec ) - { - if ( index1 == index2 ) - { - return( 0.0 ); - } - index2 = (index2+1)%image_buffer_count; - snap2 = &image_buffer[index2]; - image_count--; - } - struct timeval time2 = *snap2->timestamp; + int image_count = image_buffer_count; + int index2 = (index1+1)%image_buffer_count; + if ( index2 == image_buffer_count ) + { + return( 0.0 ); + } + Snapshot *snap2 = &image_buffer[index2]; + while ( !snap2->timestamp || !snap2->timestamp->tv_sec ) + { + if ( index1 == index2 ) + { + return( 0.0 ); + } + index2 = (index2+1)%image_buffer_count; + snap2 = &image_buffer[index2]; + image_count--; + } + struct timeval time2 = *snap2->timestamp; - double time_diff = tvDiffSec( time2, time1 ); + double time_diff = tvDiffSec( time2, time1 ); - double curr_fps = image_count/time_diff; + double curr_fps = image_count/time_diff; - if ( curr_fps < 0.0 ) - { - //Error( "Negative FPS %f, time_diff = %lf (%d:%ld.%ld - %d:%ld.%ld), ibc: %d", curr_fps, time_diff, index2, time2.tv_sec, time2.tv_usec, index1, time1.tv_sec, time1.tv_usec, image_buffer_count ); - return( 0.0 ); - } - return( curr_fps ); + if ( curr_fps < 0.0 ) + { + //Error( "Negative FPS %f, time_diff = %lf (%d:%ld.%ld - %d:%ld.%ld), ibc: %d", curr_fps, time_diff, index2, time2.tv_sec, time2.tv_usec, index1, time1.tv_sec, time1.tv_usec, image_buffer_count ); + return( 0.0 ); + } + return( curr_fps ); } useconds_t Monitor::GetAnalysisRate() { - double capturing_fps = GetFPS(); - if ( !analysis_fps ) - { - return( 0 ); - } - else if ( analysis_fps > capturing_fps ) - { - Warning( "Analysis fps (%.2f) is greater than capturing fps (%.2f)", analysis_fps, capturing_fps ); - return( 0 ); - } - else - { - return( ( 1000000 / analysis_fps ) - ( 1000000 / capturing_fps ) ); - } + double capturing_fps = GetFPS(); + if ( !analysis_fps ) + { + return( 0 ); + } + else if ( analysis_fps > capturing_fps ) + { + Warning( "Analysis fps (%.2f) is greater than capturing fps (%.2f)", analysis_fps, capturing_fps ); + return( 0 ); + } + else + { + return( ( 1000000 / analysis_fps ) - ( 1000000 / capturing_fps ) ); + } } void Monitor::UpdateAdaptiveSkip() { - if ( config.opt_adaptive_skip ) - { - double capturing_fps = GetFPS(); - if ( adaptive_skip && analysis_fps && ( analysis_fps < capturing_fps ) ) - { - Info( "Analysis fps (%.2f) is lower than capturing fps (%.2f), disabling adaptive skip feature", analysis_fps, capturing_fps ); - adaptive_skip = false; - } - else if ( !adaptive_skip && ( !analysis_fps || ( analysis_fps >= capturing_fps ) ) ) - { - Info( "Enabling adaptive skip feature" ); - adaptive_skip = true; - } - } - else - { - adaptive_skip = false; - } + if ( config.opt_adaptive_skip ) + { + double capturing_fps = GetFPS(); + if ( adaptive_skip && analysis_fps && ( analysis_fps < capturing_fps ) ) + { + Info( "Analysis fps (%.2f) is lower than capturing fps (%.2f), disabling adaptive skip feature", analysis_fps, capturing_fps ); + adaptive_skip = false; + } + else if ( !adaptive_skip && ( !analysis_fps || ( analysis_fps >= capturing_fps ) ) ) + { + Info( "Enabling adaptive skip feature" ); + adaptive_skip = true; + } + } + else + { + adaptive_skip = false; + } } void Monitor::ForceAlarmOn( int force_score, const char *force_cause, const char *force_text ) { - trigger_data->trigger_state = TRIGGER_ON; - trigger_data->trigger_score = force_score; - strncpy( trigger_data->trigger_cause, force_cause, sizeof(trigger_data->trigger_cause) ); - strncpy( trigger_data->trigger_text, force_text, sizeof(trigger_data->trigger_text) ); + trigger_data->trigger_state = TRIGGER_ON; + trigger_data->trigger_score = force_score; + strncpy( trigger_data->trigger_cause, force_cause, sizeof(trigger_data->trigger_cause) ); + strncpy( trigger_data->trigger_text, force_text, sizeof(trigger_data->trigger_text) ); } void Monitor::ForceAlarmOff() { - trigger_data->trigger_state = TRIGGER_OFF; + trigger_data->trigger_state = TRIGGER_OFF; } void Monitor::CancelForced() { - trigger_data->trigger_state = TRIGGER_CANCEL; + trigger_data->trigger_state = TRIGGER_CANCEL; } void Monitor::actionReload() { - shared_data->action |= RELOAD; + shared_data->action |= RELOAD; } void Monitor::actionEnable() { - shared_data->action |= RELOAD; + shared_data->action |= RELOAD; - static char sql[ZM_SQL_SML_BUFSIZ]; - snprintf( sql, sizeof(sql), "update Monitors set Enabled = 1 where Id = '%d'", id ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + static char sql[ZM_SQL_SML_BUFSIZ]; + snprintf( sql, sizeof(sql), "update Monitors set Enabled = 1 where Id = '%d'", id ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } } void Monitor::actionDisable() { - shared_data->action |= RELOAD; + shared_data->action |= RELOAD; - static char sql[ZM_SQL_SML_BUFSIZ]; - snprintf( sql, sizeof(sql), "update Monitors set Enabled = 0 where Id = '%d'", id ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + static char sql[ZM_SQL_SML_BUFSIZ]; + snprintf( sql, sizeof(sql), "update Monitors set Enabled = 0 where Id = '%d'", id ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } } void Monitor::actionSuspend() { - shared_data->action |= SUSPEND; + shared_data->action |= SUSPEND; } void Monitor::actionResume() { - shared_data->action |= RESUME; + shared_data->action |= RESUME; } int Monitor::actionBrightness( int p_brightness ) { - if ( purpose != CAPTURE ) - { - if ( p_brightness >= 0 ) - { - shared_data->brightness = p_brightness; - shared_data->action |= SET_SETTINGS; - int wait_loops = 10; - while ( shared_data->action & SET_SETTINGS ) - { - if ( wait_loops-- ) - usleep( 100000 ); - else - { - Warning( "Timed out waiting to set brightness" ); - return( -1 ); - } - } - } - else - { - shared_data->action |= GET_SETTINGS; - int wait_loops = 10; - while ( shared_data->action & GET_SETTINGS ) - { - if ( wait_loops-- ) - usleep( 100000 ); - else - { - Warning( "Timed out waiting to get brightness" ); - return( -1 ); - } - } - } - return( shared_data->brightness ); - } - return( camera->Brightness( p_brightness ) ); + if ( purpose != CAPTURE ) + { + if ( p_brightness >= 0 ) + { + shared_data->brightness = p_brightness; + shared_data->action |= SET_SETTINGS; + int wait_loops = 10; + while ( shared_data->action & SET_SETTINGS ) + { + if ( wait_loops-- ) + usleep( 100000 ); + else + { + Warning( "Timed out waiting to set brightness" ); + return( -1 ); + } + } + } + else + { + shared_data->action |= GET_SETTINGS; + int wait_loops = 10; + while ( shared_data->action & GET_SETTINGS ) + { + if ( wait_loops-- ) + usleep( 100000 ); + else + { + Warning( "Timed out waiting to get brightness" ); + return( -1 ); + } + } + } + return( shared_data->brightness ); + } + return( camera->Brightness( p_brightness ) ); } int Monitor::actionContrast( int p_contrast ) { - if ( purpose != CAPTURE ) - { - if ( p_contrast >= 0 ) - { - shared_data->contrast = p_contrast; - shared_data->action |= SET_SETTINGS; - int wait_loops = 10; - while ( shared_data->action & SET_SETTINGS ) - { - if ( wait_loops-- ) - usleep( 100000 ); - else - { - Warning( "Timed out waiting to set contrast" ); - return( -1 ); - } - } - } - else - { - shared_data->action |= GET_SETTINGS; - int wait_loops = 10; - while ( shared_data->action & GET_SETTINGS ) - { - if ( wait_loops-- ) - usleep( 100000 ); - else - { - Warning( "Timed out waiting to get contrast" ); - return( -1 ); - } - } - } - return( shared_data->contrast ); - } - return( camera->Contrast( p_contrast ) ); + if ( purpose != CAPTURE ) + { + if ( p_contrast >= 0 ) + { + shared_data->contrast = p_contrast; + shared_data->action |= SET_SETTINGS; + int wait_loops = 10; + while ( shared_data->action & SET_SETTINGS ) + { + if ( wait_loops-- ) + usleep( 100000 ); + else + { + Warning( "Timed out waiting to set contrast" ); + return( -1 ); + } + } + } + else + { + shared_data->action |= GET_SETTINGS; + int wait_loops = 10; + while ( shared_data->action & GET_SETTINGS ) + { + if ( wait_loops-- ) + usleep( 100000 ); + else + { + Warning( "Timed out waiting to get contrast" ); + return( -1 ); + } + } + } + return( shared_data->contrast ); + } + return( camera->Contrast( p_contrast ) ); } int Monitor::actionHue( int p_hue ) { - if ( purpose != CAPTURE ) - { - if ( p_hue >= 0 ) - { - shared_data->hue = p_hue; - shared_data->action |= SET_SETTINGS; - int wait_loops = 10; - while ( shared_data->action & SET_SETTINGS ) - { - if ( wait_loops-- ) - usleep( 100000 ); - else - { - Warning( "Timed out waiting to set hue" ); - return( -1 ); - } - } - } - else - { - shared_data->action |= GET_SETTINGS; - int wait_loops = 10; - while ( shared_data->action & GET_SETTINGS ) - { - if ( wait_loops-- ) - usleep( 100000 ); - else - { - Warning( "Timed out waiting to get hue" ); - return( -1 ); - } - } - } - return( shared_data->hue ); - } - return( camera->Hue( p_hue ) ); + if ( purpose != CAPTURE ) + { + if ( p_hue >= 0 ) + { + shared_data->hue = p_hue; + shared_data->action |= SET_SETTINGS; + int wait_loops = 10; + while ( shared_data->action & SET_SETTINGS ) + { + if ( wait_loops-- ) + usleep( 100000 ); + else + { + Warning( "Timed out waiting to set hue" ); + return( -1 ); + } + } + } + else + { + shared_data->action |= GET_SETTINGS; + int wait_loops = 10; + while ( shared_data->action & GET_SETTINGS ) + { + if ( wait_loops-- ) + usleep( 100000 ); + else + { + Warning( "Timed out waiting to get hue" ); + return( -1 ); + } + } + } + return( shared_data->hue ); + } + return( camera->Hue( p_hue ) ); } int Monitor::actionColour( int p_colour ) { - if ( purpose != CAPTURE ) - { - if ( p_colour >= 0 ) - { - shared_data->colour = p_colour; - shared_data->action |= SET_SETTINGS; - int wait_loops = 10; - while ( shared_data->action & SET_SETTINGS ) - { - if ( wait_loops-- ) - usleep( 100000 ); - else - { - Warning( "Timed out waiting to set colour" ); - return( -1 ); - } - } - } - else - { - shared_data->action |= GET_SETTINGS; - int wait_loops = 10; - while ( shared_data->action & GET_SETTINGS ) - { - if ( wait_loops-- ) - usleep( 100000 ); - else - { - Warning( "Timed out waiting to get colour" ); - return( -1 ); - } - } - } - return( shared_data->colour ); - } - return( camera->Colour( p_colour ) ); + if ( purpose != CAPTURE ) + { + if ( p_colour >= 0 ) + { + shared_data->colour = p_colour; + shared_data->action |= SET_SETTINGS; + int wait_loops = 10; + while ( shared_data->action & SET_SETTINGS ) + { + if ( wait_loops-- ) + usleep( 100000 ); + else + { + Warning( "Timed out waiting to set colour" ); + return( -1 ); + } + } + } + else + { + shared_data->action |= GET_SETTINGS; + int wait_loops = 10; + while ( shared_data->action & GET_SETTINGS ) + { + if ( wait_loops-- ) + usleep( 100000 ); + else + { + Warning( "Timed out waiting to get colour" ); + return( -1 ); + } + } + } + return( shared_data->colour ); + } + return( camera->Colour( p_colour ) ); } void Monitor::DumpZoneImage( const char *zone_string ) { - int exclude_id = 0; - int extra_colour = 0; - Polygon extra_zone; + int exclude_id = 0; + int extra_colour = 0; + Polygon extra_zone; - if ( zone_string ) - { - if ( !Zone::ParseZoneString( zone_string, exclude_id, extra_colour, extra_zone ) ) - { - Error( "Failed to parse zone string, ignoring" ); - } - } + if ( zone_string ) + { + if ( !Zone::ParseZoneString( zone_string, exclude_id, extra_colour, extra_zone ) ) + { + Error( "Failed to parse zone string, ignoring" ); + } + } - Image *zone_image = NULL; - if ( ( (!staticConfig.SERVER_ID) || ( staticConfig.SERVER_ID == server_id ) ) && mem_ptr ) { - Debug(3, "Trying to load from local zmc"); - int index = shared_data->last_write_index; - Snapshot *snap = &image_buffer[index]; - zone_image = new Image( *snap->image ); - } else { - Debug(3, "Trying to load from event"); - // Grab the most revent event image - std::string sql = stringtf( "SELECT MAX(Id) FROM Events WHERE MonitorId=%d AND Frames > 0", id ); - MYSQL_ROW eventid_row = zmDbFetchOne(sql.c_str() ); - if ( eventid_row ) { - int event_id = atoi( eventid_row[0] ); + Image *zone_image = NULL; + if ( ( (!staticConfig.SERVER_ID) || ( staticConfig.SERVER_ID == server_id ) ) && mem_ptr ) { + Debug(3, "Trying to load from local zmc"); + int index = shared_data->last_write_index; + Snapshot *snap = &image_buffer[index]; + zone_image = new Image( *snap->image ); + } else { + Debug(3, "Trying to load from event"); + // Grab the most revent event image + std::string sql = stringtf( "SELECT MAX(Id) FROM Events WHERE MonitorId=%d AND Frames > 0", id ); + zmDbRow eventid_row; + if ( eventid_row.fetch( sql.c_str() ) ) { + int event_id = atoi( eventid_row[0] ); - Debug( 3, "Got event %d", event_id ); - EventStream *stream = new EventStream(); - stream->setStreamStart( event_id, 1 ); - zone_image = stream->getImage(); - } else { - Error("Unable to load an event for monitor %d", id ); - return; - } - } + Debug( 3, "Got event %d", event_id ); + EventStream *stream = new EventStream(); + stream->setStreamStart( event_id, (unsigned int)1 ); + zone_image = stream->getImage(); + } else { + Error("Unable to load an event for monitor %d", id ); + return; + } + } - if(zone_image->Colours() == ZM_COLOUR_GRAY8) { - zone_image->Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB ); - } - - for( int i = 0; i < n_zones; i++ ) - { - if ( exclude_id && (!extra_colour || extra_zone.getNumCoords()) && zones[i]->Id() == exclude_id ) - continue; + if(zone_image->Colours() == ZM_COLOUR_GRAY8) { + zone_image->Colourise(ZM_COLOUR_RGB24, ZM_SUBPIX_ORDER_RGB ); + } + + for( int i = 0; i < n_zones; i++ ) + { + if ( exclude_id && (!extra_colour || extra_zone.getNumCoords()) && zones[i]->Id() == exclude_id ) + continue; - Rgb colour; - if ( exclude_id && !extra_zone.getNumCoords() && zones[i]->Id() == exclude_id ) - { - colour = extra_colour; - } - else - { - if ( zones[i]->IsActive() ) - { - colour = RGB_RED; - } - else if ( zones[i]->IsInclusive() ) - { - colour = RGB_ORANGE; - } - else if ( zones[i]->IsExclusive() ) - { - colour = RGB_PURPLE; - } - else if ( zones[i]->IsPreclusive() ) - { - colour = RGB_BLUE; - } - else - { - colour = RGB_WHITE; - } - } - zone_image->Fill( colour, 2, zones[i]->GetPolygon() ); - zone_image->Outline( colour, zones[i]->GetPolygon() ); - } + Rgb colour; + if ( exclude_id && !extra_zone.getNumCoords() && zones[i]->Id() == exclude_id ) + { + colour = extra_colour; + } + else + { + if ( zones[i]->IsActive() ) + { + colour = RGB_RED; + } + else if ( zones[i]->IsInclusive() ) + { + colour = RGB_ORANGE; + } + else if ( zones[i]->IsExclusive() ) + { + colour = RGB_PURPLE; + } + else if ( zones[i]->IsPreclusive() ) + { + colour = RGB_BLUE; + } + else + { + colour = RGB_WHITE; + } + } + zone_image->Fill( colour, 2, zones[i]->GetPolygon() ); + zone_image->Outline( colour, zones[i]->GetPolygon() ); + } - if ( extra_zone.getNumCoords() ) - { - zone_image->Fill( extra_colour, 2, extra_zone ); - zone_image->Outline( extra_colour, extra_zone ); - } + if ( extra_zone.getNumCoords() ) + { + zone_image->Fill( extra_colour, 2, extra_zone ); + zone_image->Outline( extra_colour, extra_zone ); + } - static char filename[PATH_MAX]; - snprintf( filename, sizeof(filename), "Zones%d.jpg", id ); - zone_image->WriteJpeg( filename ); - delete zone_image; + static char filename[PATH_MAX]; + snprintf( filename, sizeof(filename), "Zones%d.jpg", id ); + zone_image->WriteJpeg( filename ); + delete zone_image; } void Monitor::DumpImage( Image *dump_image ) const { - if ( image_count && !(image_count%10) ) - { - static char filename[PATH_MAX]; - static char new_filename[PATH_MAX]; - snprintf( filename, sizeof(filename), "Monitor%d.jpg", id ); - snprintf( new_filename, sizeof(new_filename), "Monitor%d-new.jpg", id ); - dump_image->WriteJpeg( new_filename ); - rename( new_filename, filename ); - } + if ( image_count && !(image_count%10) ) + { + static char filename[PATH_MAX]; + static char new_filename[PATH_MAX]; + snprintf( filename, sizeof(filename), "Monitor%d.jpg", id ); + snprintf( new_filename, sizeof(new_filename), "Monitor%d-new.jpg", id ); + dump_image->WriteJpeg( new_filename ); + rename( new_filename, filename ); + } } bool Monitor::CheckSignal( const Image *image ) { - static bool static_undef = true; - /* RGB24 colors */ - static uint8_t red_val; - static uint8_t green_val; - static uint8_t blue_val; - static uint8_t grayscale_val; /* 8bit grayscale color */ - static Rgb colour_val; /* RGB32 color */ - static int usedsubpixorder; + static bool static_undef = true; + /* RGB24 colors */ + static uint8_t red_val; + static uint8_t green_val; + static uint8_t blue_val; + static uint8_t grayscale_val; /* 8bit grayscale color */ + static Rgb colour_val; /* RGB32 color */ + static int usedsubpixorder; - if ( config.signal_check_points > 0 ) - { - if ( static_undef ) - { - static_undef = false; - usedsubpixorder = camera->SubpixelOrder(); - colour_val = rgb_convert(signal_check_colour, ZM_SUBPIX_ORDER_BGR); /* HTML colour code is actually BGR in memory, we want RGB */ - colour_val = rgb_convert(colour_val, usedsubpixorder); - red_val = RED_VAL_BGRA(signal_check_colour); - green_val = GREEN_VAL_BGRA(signal_check_colour); - blue_val = BLUE_VAL_BGRA(signal_check_colour); - grayscale_val = signal_check_colour & 0xff; /* Clear all bytes but lowest byte */ - } + if ( config.signal_check_points > 0 ) + { + if ( static_undef ) + { + static_undef = false; + usedsubpixorder = camera->SubpixelOrder(); + colour_val = rgb_convert(signal_check_colour, ZM_SUBPIX_ORDER_BGR); /* HTML colour code is actually BGR in memory, we want RGB */ + colour_val = rgb_convert(colour_val, usedsubpixorder); + red_val = RED_VAL_BGRA(signal_check_colour); + green_val = GREEN_VAL_BGRA(signal_check_colour); + blue_val = BLUE_VAL_BGRA(signal_check_colour); + grayscale_val = signal_check_colour & 0xff; /* Clear all bytes but lowest byte */ + } - const uint8_t *buffer = image->Buffer(); - int pixels = image->Pixels(); - int width = image->Width(); - int colours = image->Colours(); + const uint8_t *buffer = image->Buffer(); + int pixels = image->Pixels(); + int width = image->Width(); + int colours = image->Colours(); - int index = 0; - for ( int i = 0; i < config.signal_check_points; i++ ) - { - while( true ) - { - index = (int)(((long long)rand()*(long long)(pixels-1))/RAND_MAX); - if ( !config.timestamp_on_capture || !label_format[0] ) - break; - // Avoid sampling the rows with timestamp in - if ( index < (label_coord.Y()*width) || index >= (label_coord.Y()+Image::LINE_HEIGHT)*width ) - break; - } - - if(colours == ZM_COLOUR_GRAY8) { - if ( *(buffer+index) != grayscale_val ) - return true; - - } else if(colours == ZM_COLOUR_RGB24) { - const uint8_t *ptr = buffer+(index*colours); - - if ( usedsubpixorder == ZM_SUBPIX_ORDER_BGR) { - if ( (RED_PTR_BGRA(ptr) != red_val) || (GREEN_PTR_BGRA(ptr) != green_val) || (BLUE_PTR_BGRA(ptr) != blue_val) ) - return true; - } else { - /* Assume RGB */ - if ( (RED_PTR_RGBA(ptr) != red_val) || (GREEN_PTR_RGBA(ptr) != green_val) || (BLUE_PTR_RGBA(ptr) != blue_val) ) - return true; - } - - } else if(colours == ZM_COLOUR_RGB32) { - if ( usedsubpixorder == ZM_SUBPIX_ORDER_ARGB || usedsubpixorder == ZM_SUBPIX_ORDER_ABGR) { - if ( ARGB_ABGR_ZEROALPHA(*(((const Rgb*)buffer)+index)) != ARGB_ABGR_ZEROALPHA(colour_val) ) - return true; - } else { - /* Assume RGBA or BGRA */ - if ( RGBA_BGRA_ZEROALPHA(*(((const Rgb*)buffer)+index)) != RGBA_BGRA_ZEROALPHA(colour_val) ) - return true; - } - } - - } - return( false ); - } - return( true ); + int index = 0; + for ( int i = 0; i < config.signal_check_points; i++ ) + { + while( true ) + { + index = (int)(((long long)rand()*(long long)(pixels-1))/RAND_MAX); + if ( !config.timestamp_on_capture || !label_format[0] ) + break; + // Avoid sampling the rows with timestamp in + if ( index < (label_coord.Y()*width) || index >= (label_coord.Y()+Image::LINE_HEIGHT)*width ) + break; + } + + if(colours == ZM_COLOUR_GRAY8) { + if ( *(buffer+index) != grayscale_val ) + return true; + + } else if(colours == ZM_COLOUR_RGB24) { + const uint8_t *ptr = buffer+(index*colours); + + if ( usedsubpixorder == ZM_SUBPIX_ORDER_BGR) { + if ( (RED_PTR_BGRA(ptr) != red_val) || (GREEN_PTR_BGRA(ptr) != green_val) || (BLUE_PTR_BGRA(ptr) != blue_val) ) + return true; + } else { + /* Assume RGB */ + if ( (RED_PTR_RGBA(ptr) != red_val) || (GREEN_PTR_RGBA(ptr) != green_val) || (BLUE_PTR_RGBA(ptr) != blue_val) ) + return true; + } + + } else if(colours == ZM_COLOUR_RGB32) { + if ( usedsubpixorder == ZM_SUBPIX_ORDER_ARGB || usedsubpixorder == ZM_SUBPIX_ORDER_ABGR) { + if ( ARGB_ABGR_ZEROALPHA(*(((const Rgb*)buffer)+index)) != ARGB_ABGR_ZEROALPHA(colour_val) ) + return true; + } else { + /* Assume RGBA or BGRA */ + if ( RGBA_BGRA_ZEROALPHA(*(((const Rgb*)buffer)+index)) != RGBA_BGRA_ZEROALPHA(colour_val) ) + return true; + } + } + + } + return( false ); + } + return( true ); } bool Monitor::Analyse() { - if ( shared_data->last_read_index == shared_data->last_write_index ) - { - return( false ); - } + if ( shared_data->last_read_index == shared_data->last_write_index ) + { + // I wonder how often this happens. Maybe if this happens we should sleep or something? + return( false ); + } - struct timeval now; - gettimeofday( &now, NULL ); + struct timeval now; + gettimeofday( &now, NULL ); - if ( image_count && fps_report_interval && !(image_count%fps_report_interval) ) - { - fps = double(fps_report_interval)/(now.tv_sec-last_fps_time); - Info( "%s: %d - Analysing at %.2f fps", name, image_count, fps ); - last_fps_time = now.tv_sec; - } + if ( image_count && fps_report_interval && !(image_count%fps_report_interval) ) + { + fps = double(fps_report_interval)/(now.tv_sec-last_fps_time); + Info( "%s: %d - Analysing at %.2f fps", name, image_count, fps ); + last_fps_time = now.tv_sec; + } - int index; - if ( adaptive_skip ) - { - int read_margin = shared_data->last_read_index - shared_data->last_write_index; - if ( read_margin < 0 ) read_margin += image_buffer_count; + int index; + if ( adaptive_skip ) + { + int read_margin = shared_data->last_read_index - shared_data->last_write_index; + if ( read_margin < 0 ) read_margin += image_buffer_count; - int step = 1; - if ( read_margin > 0 ) - { - step = (9*image_buffer_count)/(5*read_margin); - } + int step = 1; + // Isn't read_margin always > 0 here? + if ( read_margin > 0 ) + { + // TODO explain this so... 90% of image buffer / 50% of read margin? + step = (9*image_buffer_count)/(5*read_margin); + } - int pending_frames = shared_data->last_write_index - shared_data->last_read_index; - if ( pending_frames < 0 ) pending_frames += image_buffer_count; + int pending_frames = shared_data->last_write_index - shared_data->last_read_index; + if ( pending_frames < 0 ) pending_frames += image_buffer_count; - Debug( 4, "RI:%d, WI: %d, PF = %d, RM = %d, Step = %d", shared_data->last_read_index, shared_data->last_write_index, pending_frames, read_margin, step ); - if ( step <= pending_frames ) - { - index = (shared_data->last_read_index+step)%image_buffer_count; - } - else - { - if ( pending_frames ) - { - Warning( "Approaching buffer overrun, consider slowing capture, simplifying analysis or increasing ring buffer size" ); - } - index = shared_data->last_write_index%image_buffer_count; - } - } - else - { - index = shared_data->last_write_index%image_buffer_count; - } + Debug( 4, "RI:%d, WI: %d, PF = %d, RM = %d, Step = %d", shared_data->last_read_index, shared_data->last_write_index, pending_frames, read_margin, step ); + if ( step <= pending_frames ) + { + index = (shared_data->last_read_index+step)%image_buffer_count; + } + else + { + if ( pending_frames ) + { + Warning( "Approaching buffer overrun, consider slowing capture, simplifying analysis or increasing ring buffer size" ); + } + index = shared_data->last_write_index%image_buffer_count; + } + } + else + { + index = shared_data->last_write_index%image_buffer_count; + } - Snapshot *snap = &image_buffer[index]; - struct timeval *timestamp = snap->timestamp; - Image *snap_image = snap->image; + Snapshot *snap = &image_buffer[index]; + struct timeval *timestamp = snap->timestamp; + Image *snap_image = snap->image; - if ( shared_data->action ) - { - if ( shared_data->action & RELOAD ) - { - Info( "Received reload indication at count %d", image_count ); - shared_data->action &= ~RELOAD; - Reload(); - } - if ( shared_data->action & SUSPEND ) - { - if ( Active() ) - { - Info( "Received suspend indication at count %d", image_count ); - shared_data->active = false; - //closeEvent(); - } - if ( config.max_suspend_time ) - { - auto_resume_time = now.tv_sec + config.max_suspend_time; - } - shared_data->action &= ~SUSPEND; - } - if ( shared_data->action & RESUME ) - { - if ( Enabled() && !Active() ) - { - Info( "Received resume indication at count %d", image_count ); - shared_data->active = true; - ref_image = *snap_image; - ready_count = image_count+(warmup_count/2); - shared_data->alarm_x = shared_data->alarm_y = -1; - } - shared_data->action &= ~RESUME; - } - } - if ( auto_resume_time && (now.tv_sec >= auto_resume_time) ) - { - Info( "Auto resuming at count %d", image_count ); - shared_data->active = true; - ref_image = *snap_image; - ready_count = image_count+(warmup_count/2); - auto_resume_time = 0; - } + if ( shared_data->action ) + { + if ( shared_data->action & RELOAD ) + { + Info( "Received reload indication at count %d", image_count ); + shared_data->action &= ~RELOAD; + Reload(); + } + if ( shared_data->action & SUSPEND ) + { + if ( Active() ) + { + Info( "Received suspend indication at count %d", image_count ); + shared_data->active = false; + //closeEvent(); + } + if ( config.max_suspend_time ) + { + auto_resume_time = now.tv_sec + config.max_suspend_time; + } + shared_data->action &= ~SUSPEND; + } + if ( shared_data->action & RESUME ) + { + if ( Enabled() && !Active() ) + { + Info( "Received resume indication at count %d", image_count ); + shared_data->active = true; + ref_image = *snap_image; + ready_count = image_count+(warmup_count/2); + shared_data->alarm_x = shared_data->alarm_y = -1; + } + shared_data->action &= ~RESUME; + } + } + if ( auto_resume_time && (now.tv_sec >= auto_resume_time) ) + { + Info( "Auto resuming at count %d", image_count ); + shared_data->active = true; + ref_image = *snap_image; + ready_count = image_count+(warmup_count/2); + auto_resume_time = 0; + } - static bool static_undef = true; - static int last_section_mod = 0; - static bool last_signal; + static bool static_undef = true; + static int last_section_mod = 0; + static bool last_signal; - if ( static_undef ) - { - static_undef = false; - timestamps = new struct timeval *[pre_event_count]; - images = new Image *[pre_event_count]; - last_signal = shared_data->signal; - } + if ( static_undef ) + { +// Sure would be nice to be able to assume that these were already initialized. It's just 1 compare/branch, but really not neccessary. + static_undef = false; + timestamps = new struct timeval *[pre_event_count]; + images = new Image *[pre_event_count]; + last_signal = shared_data->signal; + } - if ( Enabled() ) - { - bool signal = shared_data->signal; - bool signal_change = (signal != last_signal); - - //Set video recording flag for event start constructor and easy reference in code - bool videoRecording = ((GetOptVideoWriter() == 2) && camera->SupportsNativeVideo()); - - if ( trigger_data->trigger_state != TRIGGER_OFF ) - { - unsigned int score = 0; - if ( Ready() ) - { - std::string cause; - Event::StringSetMap noteSetMap; + if ( Enabled() ) + { + bool signal = shared_data->signal; + bool signal_change = (signal != last_signal); + + //Set video recording flag for event start constructor and easy reference in code + // TODO: Use enum instead of the # 2. Makes for easier reading + bool videoRecording = ((GetOptVideoWriter() == 2) && camera->SupportsNativeVideo()); + + if ( trigger_data->trigger_state != TRIGGER_OFF ) + { + unsigned int score = 0; + if ( Ready() ) + { + std::string cause; + Event::StringSetMap noteSetMap; - if ( trigger_data->trigger_state == TRIGGER_ON ) - { - score += trigger_data->trigger_score; - if ( !event ) - { - if ( cause.length() ) - cause += ", "; - cause += trigger_data->trigger_cause; - } - Event::StringSet noteSet; - noteSet.insert( trigger_data->trigger_text ); - noteSetMap[trigger_data->trigger_cause] = noteSet; - } - if ( signal_change ) - { - const char *signalText; - if ( !signal ) - signalText = "Lost"; - else - { - signalText = "Reacquired"; - score += 100; - } - Warning( "%s: %s", SIGNAL_CAUSE, signalText ); - if ( event && !signal ) - { - Info( "%s: %03d - Closing event %d, signal loss", name, image_count, event->Id() ); - closeEvent(); - last_section_mod = 0; - } - if ( !event ) - { - if ( cause.length() ) - cause += ", "; - cause += SIGNAL_CAUSE; - } - Event::StringSet noteSet; - noteSet.insert( signalText ); - noteSetMap[SIGNAL_CAUSE] = noteSet; - shared_data->state = state = IDLE; - shared_data->active = signal; - ref_image = *snap_image; - } - else if ( signal && Active() && (function == MODECT || function == MOCORD) ) - { - Event::StringSet zoneSet; - int motion_score = last_motion_score; - if ( !(image_count % (motion_frame_skip+1) ) ) - { - // Get new score. - motion_score = last_motion_score = DetectMotion( *snap_image, zoneSet ); - } - //int motion_score = DetectBlack( *snap_image, zoneSet ); - if ( motion_score ) - { - if ( !event ) - { - score += motion_score; - if ( cause.length() ) - cause += ", "; - cause += MOTION_CAUSE; - } - else - { - score += motion_score; - } - noteSetMap[MOTION_CAUSE] = zoneSet; + if ( trigger_data->trigger_state == TRIGGER_ON ) + { + score += trigger_data->trigger_score; + if ( !event ) + { + if ( cause.length() ) + cause += ", "; + cause += trigger_data->trigger_cause; + } + Event::StringSet noteSet; + noteSet.insert( trigger_data->trigger_text ); + noteSetMap[trigger_data->trigger_cause] = noteSet; + } + if ( signal_change ) + { + const char *signalText; + if ( !signal ) + signalText = "Lost"; + else + { + signalText = "Reacquired"; + score += 100; + } + Warning( "%s: %s", SIGNAL_CAUSE, signalText ); + if ( event && !signal ) + { + Info( "%s: %03d - Closing event %d, signal loss", name, image_count, event->Id() ); + closeEvent(); + last_section_mod = 0; + } + if ( !event ) + { + if ( cause.length() ) + cause += ", "; + cause += SIGNAL_CAUSE; + } + Event::StringSet noteSet; + noteSet.insert( signalText ); + noteSetMap[SIGNAL_CAUSE] = noteSet; + shared_data->state = state = IDLE; + shared_data->active = signal; + ref_image = *snap_image; + } + else if ( signal && Active() && (function == MODECT || function == MOCORD) ) + { + Event::StringSet zoneSet; + int motion_score = last_motion_score; + if ( !(image_count % (motion_frame_skip+1) ) ) + { + // Get new score. + motion_score = last_motion_score = DetectMotion( *snap_image, zoneSet ); + } + //int motion_score = DetectBlack( *snap_image, zoneSet ); + if ( motion_score ) + { + if ( !event ) + { + score += motion_score; + if ( cause.length() ) + cause += ", "; + cause += MOTION_CAUSE; + } + else + { + score += motion_score; + } + noteSetMap[MOTION_CAUSE] = zoneSet; - } - shared_data->active = signal; - } - if ( (!signal_change && signal) && n_linked_monitors > 0 ) - { - bool first_link = true; - Event::StringSet noteSet; - for ( int i = 0; i < n_linked_monitors; i++ ) - { - if ( linked_monitors[i]->isConnected() ) - { - if ( linked_monitors[i]->hasAlarmed() ) - { - if ( !event ) - { - if ( first_link ) - { - if ( cause.length() ) - cause += ", "; - cause += LINKED_CAUSE; - first_link = false; - } - } - noteSet.insert( linked_monitors[i]->Name() ); - score += 50; - } - } - else - { - linked_monitors[i]->connect(); - } - } - if ( noteSet.size() > 0 ) - noteSetMap[LINKED_CAUSE] = noteSet; - } - - //TODO: What happens is the event closes and sets recording to false then recording to true again so quickly that our capture daemon never picks it up. Maybe need a refresh flag? - if ( (!signal_change && signal) && (function == RECORD || function == MOCORD) ) - { - if ( event ) - { - //TODO: We shouldn't have to do this every time. Not sure why it clears itself if this isn't here?? - snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile()); - - int section_mod = timestamp->tv_sec%section_length; - if ( section_mod < last_section_mod ) - { - if ( state == IDLE || state == TAPE || event_close_mode == CLOSE_TIME ) - { - if ( state == TAPE ) - { - shared_data->state = state = IDLE; - Info( "%s: %03d - Closing event %d, section end", name, image_count, event->Id() ) - } - else - Info( "%s: %03d - Closing event %d, section end forced ", name, image_count, event->Id() ); - closeEvent(); - last_section_mod = 0; - } - } - else - { - last_section_mod = section_mod; - } - } - if ( !event ) - { + } + shared_data->active = signal; + } + if ( (!signal_change && signal) && n_linked_monitors > 0 ) + { + bool first_link = true; + Event::StringSet noteSet; + for ( int i = 0; i < n_linked_monitors; i++ ) + { + if ( linked_monitors[i]->isConnected() ) + { + if ( linked_monitors[i]->hasAlarmed() ) + { + if ( !event ) + { + if ( first_link ) + { + if ( cause.length() ) + cause += ", "; + cause += LINKED_CAUSE; + first_link = false; + } + } + noteSet.insert( linked_monitors[i]->Name() ); + score += 50; + } + } + else + { + linked_monitors[i]->connect(); + } + } + if ( noteSet.size() > 0 ) + noteSetMap[LINKED_CAUSE] = noteSet; + } + + //TODO: What happens is the event closes and sets recording to false then recording to true again so quickly that our capture daemon never picks it up. Maybe need a refresh flag? + if ( (!signal_change && signal) && (function == RECORD || function == MOCORD) ) + { + if ( event ) + { + //TODO: We shouldn't have to do this every time. Not sure why it clears itself if this isn't here?? + snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile()); + + int section_mod = timestamp->tv_sec%section_length; + if ( section_mod < last_section_mod ) + { + if ( state == IDLE || state == TAPE || event_close_mode == CLOSE_TIME ) + { + if ( state == TAPE ) + { + shared_data->state = state = IDLE; + Info( "%s: %03d - Closing event %d, section end", name, image_count, event->Id() ) + } + else + Info( "%s: %03d - Closing event %d, section end forced ", name, image_count, event->Id() ); + closeEvent(); + last_section_mod = 0; + } + } + else + { + last_section_mod = section_mod; + } + } + if ( !event ) + { - // Create event - event = new Event( this, *timestamp, "Continuous", noteSetMap, videoRecording ); - shared_data->last_event = event->Id(); - //set up video store data - snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile()); - video_store_data->recording = true; - - Info( "%s: %03d - Opening new event %d, section start", name, image_count, event->Id() ); + // Create event + event = new Event( this, *timestamp, "Continuous", noteSetMap, videoRecording ); + shared_data->last_event = event->Id(); + //set up video store data + snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile()); + video_store_data->recording = true; + + Info( "%s: %03d - Opening new event %d, section start", name, image_count, event->Id() ); - /* To prevent cancelling out an existing alert\prealarm\alarm state */ - if ( state == IDLE ) - { - shared_data->state = state = TAPE; - } + /* To prevent cancelling out an existing alert\prealarm\alarm state */ + if ( state == IDLE ) + { + shared_data->state = state = TAPE; + } - //if ( config.overlap_timed_events ) - if ( false ) - { - int pre_index; - int pre_event_images = pre_event_count; + //if ( config.overlap_timed_events ) + if ( false ) + { + int pre_index; + int pre_event_images = pre_event_count; - if ( analysis_fps ) - { - // If analysis fps is set, - // compute the index for pre event images in the dedicated buffer - pre_index = image_count%pre_event_buffer_count; + if ( analysis_fps ) + { + // If analysis fps is set, + // compute the index for pre event images in the dedicated buffer + pre_index = image_count%pre_event_buffer_count; - // Seek forward the next filled slot in to the buffer (oldest data) - // from the current position - while ( pre_event_images && !pre_event_buffer[pre_index].timestamp->tv_sec ) - { - pre_index = (pre_index + 1)%pre_event_buffer_count; - // Slot is empty, removing image from counter - pre_event_images--; - } - } - else - { - // If analysis fps is not set (analysis performed at capturing framerate), - // compute the index for pre event images in the capturing buffer - pre_index = ((index + image_buffer_count) - pre_event_count)%image_buffer_count; + // Seek forward the next filled slot in to the buffer (oldest data) + // from the current position + while ( pre_event_images && !pre_event_buffer[pre_index].timestamp->tv_sec ) + { + pre_index = (pre_index + 1)%pre_event_buffer_count; + // Slot is empty, removing image from counter + pre_event_images--; + } + } + else + { + // If analysis fps is not set (analysis performed at capturing framerate), + // compute the index for pre event images in the capturing buffer + pre_index = ((index + image_buffer_count) - pre_event_count)%image_buffer_count; - // Seek forward the next filled slot in to the buffer (oldest data) - // from the current position - while ( pre_event_images && !image_buffer[pre_index].timestamp->tv_sec ) - { - pre_index = (pre_index + 1)%image_buffer_count; - // Slot is empty, removing image from counter - pre_event_images--; - } - } + // Seek forward the next filled slot in to the buffer (oldest data) + // from the current position + while ( pre_event_images && !image_buffer[pre_index].timestamp->tv_sec ) + { + pre_index = (pre_index + 1)%image_buffer_count; + // Slot is empty, removing image from counter + pre_event_images--; + } + } - if ( pre_event_images ) - { - if ( analysis_fps ) - for ( int i = 0; i < pre_event_images; i++ ) - { - timestamps[i] = pre_event_buffer[pre_index].timestamp; - images[i] = pre_event_buffer[pre_index].image; - pre_index = (pre_index + 1)%pre_event_buffer_count; - } - else - for ( int i = 0; i < pre_event_images; i++ ) - { - timestamps[i] = image_buffer[pre_index].timestamp; - images[i] = image_buffer[pre_index].image; - pre_index = (pre_index + 1)%image_buffer_count; - } + if ( pre_event_images ) + { + if ( analysis_fps ) + for ( int i = 0; i < pre_event_images; i++ ) + { + timestamps[i] = pre_event_buffer[pre_index].timestamp; + images[i] = pre_event_buffer[pre_index].image; + pre_index = (pre_index + 1)%pre_event_buffer_count; + } + else + for ( int i = 0; i < pre_event_images; i++ ) + { + timestamps[i] = image_buffer[pre_index].timestamp; + images[i] = image_buffer[pre_index].image; + pre_index = (pre_index + 1)%image_buffer_count; + } - event->AddFrames( pre_event_images, images, timestamps ); - } - } - } - } - if ( score ) - { - if ( (state == IDLE || state == TAPE || state == PREALARM ) ) - { - if ( Event::PreAlarmCount() >= (alarm_frame_count-1) ) - { - Info( "%s: %03d - Gone into alarm state", name, image_count ); - shared_data->state = state = ALARM; - if ( signal_change || (function != MOCORD && state != ALERT) ) - { - int pre_index; - int pre_event_images = pre_event_count; + event->AddFrames( pre_event_images, images, timestamps ); + } + } + } + } + if ( score ) + { + if ( (state == IDLE || state == TAPE || state == PREALARM ) ) + { + if ( Event::PreAlarmCount() >= (alarm_frame_count-1) ) + { + Info( "%s: %03d - Gone into alarm state", name, image_count ); + shared_data->state = state = ALARM; + if ( signal_change || (function != MOCORD && state != ALERT) ) + { + int pre_index; + int pre_event_images = pre_event_count; - if ( analysis_fps ) - { - // If analysis fps is set, - // compute the index for pre event images in the dedicated buffer - pre_index = image_count%pre_event_buffer_count; + if ( analysis_fps ) + { + // If analysis fps is set, + // compute the index for pre event images in the dedicated buffer + pre_index = image_count%pre_event_buffer_count; - // Seek forward the next filled slot in to the buffer (oldest data) - // from the current position - while ( pre_event_images && !pre_event_buffer[pre_index].timestamp->tv_sec ) - { - pre_index = (pre_index + 1)%pre_event_buffer_count; - // Slot is empty, removing image from counter - pre_event_images--; - } + // Seek forward the next filled slot in to the buffer (oldest data) + // from the current position + while ( pre_event_images && !pre_event_buffer[pre_index].timestamp->tv_sec ) + { + pre_index = (pre_index + 1)%pre_event_buffer_count; + // Slot is empty, removing image from counter + pre_event_images--; + } - event = new Event( this, *(pre_event_buffer[pre_index].timestamp), cause, noteSetMap ); - } - else - { - // If analysis fps is not set (analysis performed at capturing framerate), - // compute the index for pre event images in the capturing buffer - if ( alarm_frame_count > 1 ) - pre_index = ((index + image_buffer_count) - ((alarm_frame_count - 1) + pre_event_count))%image_buffer_count; - else - pre_index = ((index + image_buffer_count) - pre_event_count)%image_buffer_count; + event = new Event( this, *(pre_event_buffer[pre_index].timestamp), cause, noteSetMap ); + } + else + { + // If analysis fps is not set (analysis performed at capturing framerate), + // compute the index for pre event images in the capturing buffer + if ( alarm_frame_count > 1 ) + pre_index = ((index + image_buffer_count) - ((alarm_frame_count - 1) + pre_event_count))%image_buffer_count; + else + pre_index = ((index + image_buffer_count) - pre_event_count)%image_buffer_count; - // Seek forward the next filled slot in to the buffer (oldest data) - // from the current position - while ( pre_event_images && !image_buffer[pre_index].timestamp->tv_sec ) - { - pre_index = (pre_index + 1)%image_buffer_count; - // Slot is empty, removing image from counter - pre_event_images--; - } + // Seek forward the next filled slot in to the buffer (oldest data) + // from the current position + while ( pre_event_images && !image_buffer[pre_index].timestamp->tv_sec ) + { + pre_index = (pre_index + 1)%image_buffer_count; + // Slot is empty, removing image from counter + pre_event_images--; + } - event = new Event( this, *(image_buffer[pre_index].timestamp), cause, noteSetMap ); - } - shared_data->last_event = event->Id(); - //set up video store data - snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile()); - video_store_data->recording = true; + event = new Event( this, *(image_buffer[pre_index].timestamp), cause, noteSetMap ); + } + shared_data->last_event = event->Id(); + //set up video store data + snprintf(video_store_data->event_file, sizeof(video_store_data->event_file), "%s", event->getEventFile()); + video_store_data->recording = true; - Info( "%s: %03d - Opening new event %d, alarm start", name, image_count, event->Id() ); + Info( "%s: %03d - Opening new event %d, alarm start", name, image_count, event->Id() ); - if ( pre_event_images ) - { - if ( analysis_fps ) - for ( int i = 0; i < pre_event_images; i++ ) - { - timestamps[i] = pre_event_buffer[pre_index].timestamp; - images[i] = pre_event_buffer[pre_index].image; - pre_index = (pre_index + 1)%pre_event_buffer_count; - } - else - for ( int i = 0; i < pre_event_images; i++ ) - { - timestamps[i] = image_buffer[pre_index].timestamp; - images[i] = image_buffer[pre_index].image; - pre_index = (pre_index + 1)%image_buffer_count; - } + if ( pre_event_images ) + { + if ( analysis_fps ) + for ( int i = 0; i < pre_event_images; i++ ) + { + timestamps[i] = pre_event_buffer[pre_index].timestamp; + images[i] = pre_event_buffer[pre_index].image; + pre_index = (pre_index + 1)%pre_event_buffer_count; + } + else + for ( int i = 0; i < pre_event_images; i++ ) + { + timestamps[i] = image_buffer[pre_index].timestamp; + images[i] = image_buffer[pre_index].image; + pre_index = (pre_index + 1)%image_buffer_count; + } - event->AddFrames( pre_event_images, images, timestamps ); - } - if ( alarm_frame_count ) - { - event->SavePreAlarmFrames(); - } - } - } - else if ( state != PREALARM ) - { - Info( "%s: %03d - Gone into prealarm state", name, image_count ); - shared_data->state = state = PREALARM; - } - } - else if ( state == ALERT ) - { - Info( "%s: %03d - Gone back into alarm state", name, image_count ); - shared_data->state = state = ALARM; - } - last_alarm_count = image_count; - } - else - { - if ( state == ALARM ) - { - Info( "%s: %03d - Gone into alert state", name, image_count ); - shared_data->state = state = ALERT; - } - else if ( state == ALERT ) - { - if ( image_count-last_alarm_count > post_event_count ) - { - Info( "%s: %03d - Left alarm state (%d) - %d(%d) images", name, image_count, event->Id(), event->Frames(), event->AlarmFrames() ); - //if ( function != MOCORD || event_close_mode == CLOSE_ALARM || event->Cause() == SIGNAL_CAUSE ) - if ( function != MOCORD || event_close_mode == CLOSE_ALARM ) - { - shared_data->state = state = IDLE; - Info( "%s: %03d - Closing event %d, alarm end%s", name, image_count, event->Id(), (function==MOCORD)?", section truncated":"" ); - closeEvent(); - } - else - { - shared_data->state = state = TAPE; - } - } - } - if ( state == PREALARM ) - { - if ( function != MOCORD ) - { - shared_data->state = state = IDLE; - } - else - { - shared_data->state = state = TAPE; - } - } - if ( Event::PreAlarmCount() ) - Event::EmptyPreAlarmFrames(); - } - if ( state != IDLE ) - { - if ( state == PREALARM || state == ALARM ) - { - if ( config.create_analysis_images ) - { - bool got_anal_image = false; - alarm_image.Assign( *snap_image ); - for( int i = 0; i < n_zones; i++ ) - { - if ( zones[i]->Alarmed() ) - { - if ( zones[i]->AlarmImage() ) - { - alarm_image.Overlay( *(zones[i]->AlarmImage()) ); - got_anal_image = true; - } - if ( config.record_event_stats && state == ALARM ) - { - zones[i]->RecordStats( event ); - } - } - } - if ( got_anal_image ) - { - if ( state == PREALARM ) - Event::AddPreAlarmFrame( snap_image, *timestamp, score, &alarm_image ); - else - event->AddFrame( snap_image, *timestamp, score, &alarm_image ); - } - else - { - if ( state == PREALARM ) - Event::AddPreAlarmFrame( snap_image, *timestamp, score ); - else - event->AddFrame( snap_image, *timestamp, score ); - } - } - else - { - for( int i = 0; i < n_zones; i++ ) - { - if ( zones[i]->Alarmed() ) - { - if ( config.record_event_stats && state == ALARM ) - { - zones[i]->RecordStats( event ); - } - } - } - if ( state == PREALARM ) - Event::AddPreAlarmFrame( snap_image, *timestamp, score ); - else - event->AddFrame( snap_image, *timestamp, score ); - } - if ( event && noteSetMap.size() > 0 ) - event->updateNotes( noteSetMap ); - } - else if ( state == ALERT ) - { - event->AddFrame( snap_image, *timestamp ); - if ( noteSetMap.size() > 0 ) - event->updateNotes( noteSetMap ); - } - else if ( state == TAPE ) - { - //Video Storage: activate only for supported cameras. Event::AddFrame knows whether or not we are recording video and saves frames accordingly - if((GetOptVideoWriter() == 2) && camera->SupportsNativeVideo()) - { - video_store_data->recording = true; - } - if ( !(image_count%(frame_skip+1)) ) - { - if ( config.bulk_frame_interval > 1 ) - { - event->AddFrame( snap_image, *timestamp, (event->Frames()AddFrame( snap_image, *timestamp ); - } - } - } - } - } - } - else - { - if ( event ) - { - Info( "%s: %03d - Closing event %d, trigger off", name, image_count, event->Id() ); - closeEvent(); - } - shared_data->state = state = IDLE; - last_section_mod = 0; - } - if ( (!signal_change && signal) && (function == MODECT || function == MOCORD) ) - { - if ( state == ALARM ) { - ref_image.Blend( *snap_image, alarm_ref_blend_perc ); - } else { - ref_image.Blend( *snap_image, ref_blend_perc ); - } - } - last_signal = signal; - } + event->AddFrames( pre_event_images, images, timestamps ); + } + if ( alarm_frame_count ) + { + event->SavePreAlarmFrames(); + } + } + } + else if ( state != PREALARM ) + { + Info( "%s: %03d - Gone into prealarm state", name, image_count ); + shared_data->state = state = PREALARM; + } + } + else if ( state == ALERT ) + { + Info( "%s: %03d - Gone back into alarm state", name, image_count ); + shared_data->state = state = ALARM; + } + last_alarm_count = image_count; + } + else + { + if ( state == ALARM ) + { + Info( "%s: %03d - Gone into alert state", name, image_count ); + shared_data->state = state = ALERT; + } + else if ( state == ALERT ) + { + if ( image_count-last_alarm_count > post_event_count ) + { + Info( "%s: %03d - Left alarm state (%d) - %d(%d) images", name, image_count, event->Id(), event->Frames(), event->AlarmFrames() ); + //if ( function != MOCORD || event_close_mode == CLOSE_ALARM || event->Cause() == SIGNAL_CAUSE ) + if ( function != MOCORD || event_close_mode == CLOSE_ALARM ) + { + shared_data->state = state = IDLE; + Info( "%s: %03d - Closing event %d, alarm end%s", name, image_count, event->Id(), (function==MOCORD)?", section truncated":"" ); + closeEvent(); + } + else + { + shared_data->state = state = TAPE; + } + } + } + if ( state == PREALARM ) + { + if ( function != MOCORD ) + { + shared_data->state = state = IDLE; + } + else + { + shared_data->state = state = TAPE; + } + } + if ( Event::PreAlarmCount() ) + Event::EmptyPreAlarmFrames(); + } + if ( state != IDLE ) + { + if ( state == PREALARM || state == ALARM ) + { + if ( config.create_analysis_images ) + { + bool got_anal_image = false; + alarm_image.Assign( *snap_image ); + for( int i = 0; i < n_zones; i++ ) + { + if ( zones[i]->Alarmed() ) + { + if ( zones[i]->AlarmImage() ) + { + alarm_image.Overlay( *(zones[i]->AlarmImage()) ); + got_anal_image = true; + } + if ( config.record_event_stats && state == ALARM ) + { + zones[i]->RecordStats( event ); + } + } + } + if ( got_anal_image ) + { + if ( state == PREALARM ) + Event::AddPreAlarmFrame( snap_image, *timestamp, score, &alarm_image ); + else + event->AddFrame( snap_image, *timestamp, score, &alarm_image ); + } + else + { + if ( state == PREALARM ) + Event::AddPreAlarmFrame( snap_image, *timestamp, score ); + else + event->AddFrame( snap_image, *timestamp, score ); + } + } + else + { + for( int i = 0; i < n_zones; i++ ) + { + if ( zones[i]->Alarmed() ) + { + if ( config.record_event_stats && state == ALARM ) + { + zones[i]->RecordStats( event ); + } + } + } + if ( state == PREALARM ) + Event::AddPreAlarmFrame( snap_image, *timestamp, score ); + else + event->AddFrame( snap_image, *timestamp, score ); + } + if ( event && noteSetMap.size() > 0 ) + event->updateNotes( noteSetMap ); + } + else if ( state == ALERT ) + { + event->AddFrame( snap_image, *timestamp ); + if ( noteSetMap.size() > 0 ) + event->updateNotes( noteSetMap ); + } + else if ( state == TAPE ) + { + //Video Storage: activate only for supported cameras. Event::AddFrame knows whether or not we are recording video and saves frames accordingly + if((GetOptVideoWriter() == 2) && camera->SupportsNativeVideo()) + { + video_store_data->recording = true; + } + if ( !(image_count%(frame_skip+1)) ) + { + if ( config.bulk_frame_interval > 1 ) + { + event->AddFrame( snap_image, *timestamp, (event->Frames()AddFrame( snap_image, *timestamp ); + } + } + } + } + } + } + else + { + if ( event ) + { + Info( "%s: %03d - Closing event %d, trigger off", name, image_count, event->Id() ); + closeEvent(); + } + shared_data->state = state = IDLE; + last_section_mod = 0; + } + if ( (!signal_change && signal) && (function == MODECT || function == MOCORD) ) + { + if ( state == ALARM ) { + ref_image.Blend( *snap_image, alarm_ref_blend_perc ); + } else { + ref_image.Blend( *snap_image, ref_blend_perc ); + } + } + last_signal = signal; + } - shared_data->last_read_index = index%image_buffer_count; - //shared_data->last_read_time = image_buffer[index].timestamp->tv_sec; - shared_data->last_read_time = now.tv_sec; + shared_data->last_read_index = index%image_buffer_count; + //shared_data->last_read_time = image_buffer[index].timestamp->tv_sec; + shared_data->last_read_time = now.tv_sec; - if ( analysis_fps ) - { - // If analysis fps is set, add analysed image to dedicated pre event buffer - int pre_index = image_count%pre_event_buffer_count; - pre_event_buffer[pre_index].image->Assign(*snap->image); - memcpy( pre_event_buffer[pre_index].timestamp, snap->timestamp, sizeof(struct timeval) ); - } + if ( analysis_fps ) + { + // If analysis fps is set, add analysed image to dedicated pre event buffer + int pre_index = image_count%pre_event_buffer_count; + pre_event_buffer[pre_index].image->Assign(*snap->image); + memcpy( pre_event_buffer[pre_index].timestamp, snap->timestamp, sizeof(struct timeval) ); + } - image_count++; + image_count++; - return( true ); + return( true ); } void Monitor::Reload() { - Debug( 1, "Reloading monitor %s", name ); + Debug( 1, "Reloading monitor %s", name ); - if ( event ) - Info( "%s: %03d - Closing event %d, reloading", name, image_count, event->Id() ); + if ( event ) + Info( "%s: %03d - Closing event %d, reloading", name, image_count, event->Id() ); - closeEvent(); + closeEvent(); - static char sql[ZM_SQL_MED_BUFSIZ]; - // This seems to have fallen out of date. - snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id ); + static char sql[ZM_SQL_MED_BUFSIZ]; + // This seems to have fallen out of date. + snprintf( sql, sizeof(sql), "select Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour from Monitors where Id = '%d'", id ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - MYSQL_RES *result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - int n_monitors = mysql_num_rows( result ); - if ( n_monitors != 1 ) - { - Error( "Bogus number of monitors, %d, returned. Can't reload", n_monitors ); - return; - } + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) + { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + int n_monitors = mysql_num_rows( result ); + if ( n_monitors != 1 ) + { + Error( "Bogus number of monitors, %d, returned. Can't reload", n_monitors ); + return; + } - if ( MYSQL_ROW dbrow = mysql_fetch_row( result ) ) - { - int index = 0; - function = (Function)atoi(dbrow[index++]); - enabled = atoi(dbrow[index++]); - const char *p_linked_monitors = dbrow[index++]; - strncpy( event_prefix, dbrow[index++], sizeof(event_prefix) ); - strncpy( label_format, dbrow[index++], sizeof(label_format) ); - label_coord = Coord( atoi(dbrow[index]), atoi(dbrow[index+1]) ); index += 2; - label_size = atoi(dbrow[index++]); - warmup_count = atoi(dbrow[index++]); - pre_event_count = atoi(dbrow[index++]); - post_event_count = atoi(dbrow[index++]); - alarm_frame_count = atoi(dbrow[index++]); - section_length = atoi(dbrow[index++]); - frame_skip = atoi(dbrow[index++]); - motion_frame_skip = atoi(dbrow[index++]); - analysis_fps = dbrow[index] ? strtod(dbrow[index], NULL) : 0; index++; - analysis_update_delay = strtoul(dbrow[index++], NULL, 0); - capture_delay = (dbrow[index]&&atof(dbrow[index])>0.0)?int(DT_PREC_3/atof(dbrow[index])):0; index++; - alarm_capture_delay = (dbrow[index]&&atof(dbrow[index])>0.0)?int(DT_PREC_3/atof(dbrow[index])):0; index++; - fps_report_interval = atoi(dbrow[index++]); - ref_blend_perc = atoi(dbrow[index++]); - alarm_ref_blend_perc = atoi(dbrow[index++]); - track_motion = atoi(dbrow[index++]); - + if ( MYSQL_ROW dbrow = mysql_fetch_row( result ) ) + { + int index = 0; + function = (Function)atoi(dbrow[index++]); + enabled = atoi(dbrow[index++]); + const char *p_linked_monitors = dbrow[index++]; + strncpy( event_prefix, dbrow[index++], sizeof(event_prefix) ); + strncpy( label_format, dbrow[index++], sizeof(label_format) ); + label_coord = Coord( atoi(dbrow[index]), atoi(dbrow[index+1]) ); index += 2; + label_size = atoi(dbrow[index++]); + warmup_count = atoi(dbrow[index++]); + pre_event_count = atoi(dbrow[index++]); + post_event_count = atoi(dbrow[index++]); + alarm_frame_count = atoi(dbrow[index++]); + section_length = atoi(dbrow[index++]); + frame_skip = atoi(dbrow[index++]); + motion_frame_skip = atoi(dbrow[index++]); + analysis_fps = dbrow[index] ? strtod(dbrow[index], NULL) : 0; index++; + analysis_update_delay = strtoul(dbrow[index++], NULL, 0); + capture_delay = (dbrow[index]&&atof(dbrow[index])>0.0)?int(DT_PREC_3/atof(dbrow[index])):0; index++; + alarm_capture_delay = (dbrow[index]&&atof(dbrow[index])>0.0)?int(DT_PREC_3/atof(dbrow[index])):0; index++; + fps_report_interval = atoi(dbrow[index++]); + ref_blend_perc = atoi(dbrow[index++]); + alarm_ref_blend_perc = atoi(dbrow[index++]); + track_motion = atoi(dbrow[index++]); + - if ( dbrow[index][0] == '#' ) - signal_check_colour = strtol(dbrow[index]+1,0,16); - else - signal_check_colour = strtol(dbrow[index],0,16); - index++; + if ( dbrow[index][0] == '#' ) + signal_check_colour = strtol(dbrow[index]+1,0,16); + else + signal_check_colour = strtol(dbrow[index],0,16); + index++; - shared_data->state = state = IDLE; - shared_data->alarm_x = shared_data->alarm_y = -1; - if ( enabled ) - shared_data->active = true; - ready_count = image_count+warmup_count; + shared_data->state = state = IDLE; + shared_data->alarm_x = shared_data->alarm_y = -1; + if ( enabled ) + shared_data->active = true; + ready_count = image_count+warmup_count; - ReloadLinkedMonitors( p_linked_monitors ); - } - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - mysql_free_result( result ); + ReloadLinkedMonitors( p_linked_monitors ); + } + if ( mysql_errno( &dbconn ) ) + { + Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + mysql_free_result( result ); - ReloadZones(); + ReloadZones(); } void Monitor::ReloadZones() { - Debug( 1, "Reloading zones for monitor %s", name ); - for( int i = 0; i < n_zones; i++ ) - { - delete zones[i]; - } - delete[] zones; - zones = 0; - n_zones = Zone::Load( this, zones ); - //DumpZoneImage(); + Debug( 1, "Reloading zones for monitor %s", name ); + for( int i = 0; i < n_zones; i++ ) + { + delete zones[i]; + } + delete[] zones; + zones = 0; + n_zones = Zone::Load( this, zones ); + //DumpZoneImage(); } void Monitor::ReloadLinkedMonitors( const char *p_linked_monitors ) { - Debug( 1, "Reloading linked monitors for monitor %s, '%s'", name, p_linked_monitors ); - if ( n_linked_monitors ) - { - for( int i = 0; i < n_linked_monitors; i++ ) - { - delete linked_monitors[i]; - } - delete[] linked_monitors; - linked_monitors = 0; - } + Debug( 1, "Reloading linked monitors for monitor %s, '%s'", name, p_linked_monitors ); + if ( n_linked_monitors ) + { + for( int i = 0; i < n_linked_monitors; i++ ) + { + delete linked_monitors[i]; + } + delete[] linked_monitors; + linked_monitors = 0; + } - n_linked_monitors = 0; - if ( p_linked_monitors ) - { - int n_link_ids = 0; - unsigned int link_ids[256]; + n_linked_monitors = 0; + if ( p_linked_monitors ) + { + int n_link_ids = 0; + unsigned int link_ids[256]; - char link_id_str[8]; - char *dest_ptr = link_id_str; - const char *src_ptr = p_linked_monitors; - while( 1 ) - { - dest_ptr = link_id_str; - while( *src_ptr >= '0' && *src_ptr <= '9' ) - { - if ( (dest_ptr-link_id_str) < (unsigned int)(sizeof(link_id_str)-1) ) - { - *dest_ptr++ = *src_ptr++; - } - else - { - break; - } - } - // Add the link monitor - if ( dest_ptr != link_id_str ) - { - *dest_ptr = '\0'; - unsigned int link_id = atoi(link_id_str); - if ( link_id > 0 && link_id != id) - { - Debug( 3, "Found linked monitor id %d", link_id ); - int j; - for ( j = 0; j < n_link_ids; j++ ) - { - if ( link_ids[j] == link_id ) - break; - } - if ( j == n_link_ids ) // Not already found - { - link_ids[n_link_ids++] = link_id; - } - } - } - if ( !*src_ptr ) - break; - while( *src_ptr && (*src_ptr < '0' || *src_ptr > '9') ) - src_ptr++; - if ( !*src_ptr ) - break; - } - if ( n_link_ids > 0 ) - { - Debug( 1, "Linking to %d monitors", n_link_ids ); - linked_monitors = new MonitorLink *[n_link_ids]; - int count = 0; - for ( int i = 0; i < n_link_ids; i++ ) - { - Debug( 1, "Checking linked monitor %d", link_ids[i] ); + char link_id_str[8]; + char *dest_ptr = link_id_str; + const char *src_ptr = p_linked_monitors; + while( 1 ) + { + dest_ptr = link_id_str; + while( *src_ptr >= '0' && *src_ptr <= '9' ) + { + if ( (dest_ptr-link_id_str) < (unsigned int)(sizeof(link_id_str)-1) ) + { + *dest_ptr++ = *src_ptr++; + } + else + { + break; + } + } + // Add the link monitor + if ( dest_ptr != link_id_str ) + { + *dest_ptr = '\0'; + unsigned int link_id = atoi(link_id_str); + if ( link_id > 0 && link_id != id) + { + Debug( 3, "Found linked monitor id %d", link_id ); + int j; + for ( j = 0; j < n_link_ids; j++ ) + { + if ( link_ids[j] == link_id ) + break; + } + if ( j == n_link_ids ) // Not already found + { + link_ids[n_link_ids++] = link_id; + } + } + } + if ( !*src_ptr ) + break; + while( *src_ptr && (*src_ptr < '0' || *src_ptr > '9') ) + src_ptr++; + if ( !*src_ptr ) + break; + } + if ( n_link_ids > 0 ) + { + Debug( 1, "Linking to %d monitors", n_link_ids ); + linked_monitors = new MonitorLink *[n_link_ids]; + int count = 0; + for ( int i = 0; i < n_link_ids; i++ ) + { + Debug( 1, "Checking linked monitor %d", link_ids[i] ); - static char sql[ZM_SQL_SML_BUFSIZ]; - snprintf( sql, sizeof(sql), "select Id, Name from Monitors where Id = %d and Function != 'None' and Function != 'Monitor' and Enabled = 1", link_ids[i] ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + static char sql[ZM_SQL_SML_BUFSIZ]; + snprintf( sql, sizeof(sql), "select Id, Name from Monitors where Id = %d and Function != 'None' and Function != 'Monitor' and Enabled = 1", link_ids[i] ); + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - MYSQL_RES *result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - int n_monitors = mysql_num_rows( result ); - if ( n_monitors == 1 ) - { - MYSQL_ROW dbrow = mysql_fetch_row( result ); - Debug( 1, "Linking to monitor %d", link_ids[i] ); - linked_monitors[count++] = new MonitorLink( link_ids[i], dbrow[1] ); - } - else - { - Warning( "Can't link to monitor %d, invalid id, function or not enabled", link_ids[i] ); - } - mysql_free_result( result ); - } - n_linked_monitors = count; - } - } + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) + { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + int n_monitors = mysql_num_rows( result ); + if ( n_monitors == 1 ) + { + MYSQL_ROW dbrow = mysql_fetch_row( result ); + Debug( 1, "Linking to monitor %d", link_ids[i] ); + linked_monitors[count++] = new MonitorLink( link_ids[i], dbrow[1] ); + } + else + { + Warning( "Can't link to monitor %d, invalid id, function or not enabled", link_ids[i] ); + } + mysql_free_result( result ); + } + n_linked_monitors = count; + } + } } #if ZM_HAS_V4L int Monitor::LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ) { - std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Function != 'None' and Type = 'Local'"; + std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Method, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Function != 'None' and Type = 'Local'"; ; - if ( device[0] ) { - sql += " AND Device='"; - sql += device; - sql += "'"; - } - if ( staticConfig.SERVER_ID ) { - sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID ); - } - Debug( 1, "Loading Local Monitors with %s", sql.c_str() ); + if ( device[0] ) { + sql += " AND Device='"; + sql += device; + sql += "'"; + } + if ( staticConfig.SERVER_ID ) { + sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID ); + } + Debug( 1, "Loading Local Monitors with %s", sql.c_str() ); - MYSQL_RES *result = zmDbFetch( sql.c_str() ); - if ( !result ) { - Error( "Can't load local monitors: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - int n_monitors = mysql_num_rows( result ); - Debug( 1, "Got %d monitors", n_monitors ); - delete[] monitors; - monitors = new Monitor *[n_monitors]; - for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { - int col = 0; + MYSQL_RES *result = zmDbFetch( sql.c_str() ); + if ( !result ) { + Error( "Can't load local monitors: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + int n_monitors = mysql_num_rows( result ); + Debug( 1, "Got %d monitors", n_monitors ); + delete[] monitors; + monitors = new Monitor *[n_monitors]; + for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { + int col = 0; - int id = atoi(dbrow[col]); col++; - const char *name = dbrow[col]; col++; - unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - int function = atoi(dbrow[col]); col++; - int enabled = atoi(dbrow[col]); col++; - const char *linked_monitors = dbrow[col]; col++; + int id = atoi(dbrow[col]); col++; + const char *name = dbrow[col]; col++; + unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + int function = atoi(dbrow[col]); col++; + int enabled = atoi(dbrow[col]); col++; + const char *linked_monitors = dbrow[col]; col++; - const char *device = dbrow[col]; col++; - int channel = atoi(dbrow[col]); col++; - int format = atoi(dbrow[col]); col++; - bool v4l_multi_buffer = config.v4l_multi_buffer; - if ( dbrow[col] ) { - if (*dbrow[col] == '0' ) { - v4l_multi_buffer = false; - } else if ( *dbrow[col] == '1' ) { - v4l_multi_buffer = true; - } - } - col++; - - int v4l_captures_per_frame = 0; - if ( dbrow[col] ) { - v4l_captures_per_frame = atoi(dbrow[col]); - } else { - v4l_captures_per_frame = config.captures_per_frame; - } - Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); - col++; - const char *method = dbrow[col]; col++; + const char *device = dbrow[col]; col++; + int channel = atoi(dbrow[col]); col++; + int format = atoi(dbrow[col]); col++; + bool v4l_multi_buffer = config.v4l_multi_buffer; + if ( dbrow[col] ) { + if (*dbrow[col] == '0' ) { + v4l_multi_buffer = false; + } else if ( *dbrow[col] == '1' ) { + v4l_multi_buffer = true; + } + } + col++; + + int v4l_captures_per_frame = 0; + if ( dbrow[col] ) { + v4l_captures_per_frame = atoi(dbrow[col]); + } else { + v4l_captures_per_frame = config.captures_per_frame; + } + Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); + col++; + const char *method = dbrow[col]; col++; - int width = atoi(dbrow[col]); col++; - int height = atoi(dbrow[col]); col++; - int colours = atoi(dbrow[col]); col++; - int palette = atoi(dbrow[col]); col++; - Orientation orientation = (Orientation)atoi(dbrow[col]); col++; - unsigned int deinterlacing = atoi(dbrow[col]); col++; + int width = atoi(dbrow[col]); col++; + int height = atoi(dbrow[col]); col++; + int colours = atoi(dbrow[col]); col++; + int palette = atoi(dbrow[col]); col++; + Orientation orientation = (Orientation)atoi(dbrow[col]); col++; + unsigned int deinterlacing = atoi(dbrow[col]); col++; - int savejpegs = atoi(dbrow[col]); col++; - int videowriter = atoi(dbrow[col]); col++; - std::string encoderparams = dbrow[col]; col++; - bool record_audio = (*dbrow[col] != '0'); col++; + int savejpegs = atoi(dbrow[col]); col++; + int videowriter = atoi(dbrow[col]); col++; + std::string encoderparams = dbrow[col]; col++; + bool record_audio = (*dbrow[col] != '0'); col++; - int brightness = atoi(dbrow[col]); col++; - int contrast = atoi(dbrow[col]); col++; - int hue = atoi(dbrow[col]); col++; - int colour = atoi(dbrow[col]); col++; + int brightness = atoi(dbrow[col]); col++; + int contrast = atoi(dbrow[col]); col++; + int hue = atoi(dbrow[col]); col++; + int colour = atoi(dbrow[col]); col++; - const char *event_prefix = dbrow[col]; col++; - const char *label_format = dbrow[col]; col++; + const char *event_prefix = dbrow[col]; col++; + const char *label_format = dbrow[col]; col++; - int label_x = atoi(dbrow[col]); col++; - int label_y = atoi(dbrow[col]); col++; - int label_size = atoi(dbrow[col]); col++; + int label_x = atoi(dbrow[col]); col++; + int label_y = atoi(dbrow[col]); col++; + int label_size = atoi(dbrow[col]); col++; - int image_buffer_count = atoi(dbrow[col]); col++; - int warmup_count = atoi(dbrow[col]); col++; - int pre_event_count = atoi(dbrow[col]); col++; - int post_event_count = atoi(dbrow[col]); col++; - int stream_replay_buffer = atoi(dbrow[col]); col++; - int alarm_frame_count = atoi(dbrow[col]); col++; - int section_length = atoi(dbrow[col]); col++; - int frame_skip = atoi(dbrow[col]); col++; - int motion_frame_skip = atoi(dbrow[col]); col++; - double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; - unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); - int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int fps_report_interval = atoi(dbrow[col]); col++; - int ref_blend_perc = atoi(dbrow[col]); col++; - int alarm_ref_blend_perc = atoi(dbrow[col]); col++; - int track_motion = atoi(dbrow[col]); col++; + int image_buffer_count = atoi(dbrow[col]); col++; + int warmup_count = atoi(dbrow[col]); col++; + int pre_event_count = atoi(dbrow[col]); col++; + int post_event_count = atoi(dbrow[col]); col++; + int stream_replay_buffer = atoi(dbrow[col]); col++; + int alarm_frame_count = atoi(dbrow[col]); col++; + int section_length = atoi(dbrow[col]); col++; + int frame_skip = atoi(dbrow[col]); col++; + int motion_frame_skip = atoi(dbrow[col]); col++; + double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; + unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); + int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int fps_report_interval = atoi(dbrow[col]); col++; + int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; + int track_motion = atoi(dbrow[col]); col++; - int signal_check_colour; - if ( dbrow[col][0] == '#' ) - signal_check_colour = strtol(dbrow[col]+1,0,16); - else - signal_check_colour = strtol(dbrow[col],0,16); - col++; - bool embed_exif = (*dbrow[col] != '0'); col++; + int signal_check_colour; + if ( dbrow[col][0] == '#' ) + signal_check_colour = strtol(dbrow[col]+1,0,16); + else + signal_check_colour = strtol(dbrow[col],0,16); + col++; + bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); + int extras = (deinterlacing>>24)&0xff; - int extras = (deinterlacing>>24)&0xff; + Camera *camera = new LocalCamera( + id, + device, + channel, + format, + v4l_multi_buffer, + v4l_captures_per_frame, + method, + width, + height, + colours, + palette, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio, + extras + ); - Camera *camera = new LocalCamera( - id, - device, - channel, - format, - v4l_multi_buffer, - v4l_captures_per_frame, - method, - cam_width, - cam_height, - colours, - palette, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio, - extras - ); + monitors[i] = new Monitor( + id, + name, + server_id, + storage_id, + function, + enabled, + linked_monitors, + camera, + orientation, + deinterlacing, + savejpegs, + videowriter, + encoderparams, + record_audio, + event_prefix, + label_format, + Coord( label_x, label_y ), + label_size, + image_buffer_count, + warmup_count, + pre_event_count, + post_event_count, + stream_replay_buffer, + alarm_frame_count, + section_length, + frame_skip, + motion_frame_skip, + analysis_fps, + analysis_update_delay, + capture_delay, + alarm_capture_delay, + fps_report_interval, + ref_blend_perc, + alarm_ref_blend_perc, + track_motion, + signal_check_colour, + embed_exif, + purpose, + 0, + 0 + ); + Zone **zones = 0; + int n_zones = Zone::Load( monitors[i], zones ); + monitors[i]->AddZones( n_zones, zones ); + monitors[i]->AddPrivacyBitmask( zones ); + Debug( 1, "Loaded monitor %d(%s), %d zones", id, name, n_zones ); + } + if ( mysql_errno( &dbconn ) ) + { + Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + // Yadda yadda + mysql_free_result( result ); - monitors[i] = new Monitor( - id, - name, - server_id, - storage_id, - function, - enabled, - linked_monitors, - camera, - orientation, - deinterlacing, - savejpegs, - videowriter, - encoderparams, - record_audio, - event_prefix, - label_format, - Coord( label_x, label_y ), - label_size, - image_buffer_count, - warmup_count, - pre_event_count, - post_event_count, - stream_replay_buffer, - alarm_frame_count, - section_length, - frame_skip, - motion_frame_skip, - analysis_fps, - analysis_update_delay, - capture_delay, - alarm_capture_delay, - fps_report_interval, - ref_blend_perc, - alarm_ref_blend_perc, - track_motion, - signal_check_colour, - embed_exif, - purpose, - 0, - 0 - ); - Zone **zones = 0; - int n_zones = Zone::Load( monitors[i], zones ); - monitors[i]->AddZones( n_zones, zones ); - monitors[i]->AddPrivacyBitmask( zones ); - Debug( 1, "Loaded monitor %d(%s), %d zones", id, name, n_zones ); - } - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - // Yadda yadda - mysql_free_result( result ); - - return( n_monitors ); + return( n_monitors ); } #endif // ZM_HAS_V4L int Monitor::LoadRemoteMonitors( const char *protocol, const char *host, const char *port, const char *path, Monitor **&monitors, Purpose purpose ) { - std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'"; - if ( staticConfig.SERVER_ID ) { - sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID ); - } + std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Protocol, Method, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Remote'"; + if ( staticConfig.SERVER_ID ) { + sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID ); + } - if ( protocol ) { - sql += stringtf(" AND Protocol = '%s' and Host = '%s' and Port = '%s' and Path = '%s'", protocol, host, port, path ); - } + if ( protocol ) { + sql += stringtf(" AND Protocol = '%s' and Host = '%s' and Port = '%s' and Path = '%s'", protocol, host, port, path ); + } - Debug( 1, "Loading Remote Monitors with %s", sql.c_str() ); - MYSQL_RES *result = zmDbFetch( sql.c_str() ); - if ( !result ) { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - int n_monitors = mysql_num_rows( result ); - Debug( 1, "Got %d monitors", n_monitors ); - delete[] monitors; - monitors = new Monitor *[n_monitors]; - for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { - int col = 0; + Debug( 1, "Loading Remote Monitors with %s", sql.c_str() ); + MYSQL_RES *result = zmDbFetch( sql.c_str() ); + if ( !result ) { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + int n_monitors = mysql_num_rows( result ); + Debug( 1, "Got %d monitors", n_monitors ); + delete[] monitors; + monitors = new Monitor *[n_monitors]; + for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { + int col = 0; - int id = atoi(dbrow[col]); col++; - std::string name = dbrow[col]; col++; - unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - int function = atoi(dbrow[col]); col++; - int enabled = atoi(dbrow[col]); col++; - const char *linked_monitors = dbrow[col]; col++; + int id = atoi(dbrow[col]); col++; + std::string name = dbrow[col]; col++; + unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + int function = atoi(dbrow[col]); col++; + int enabled = atoi(dbrow[col]); col++; + const char *linked_monitors = dbrow[col]; col++; - std::string protocol = dbrow[col]; col++; - std::string method = dbrow[col]; col++; - std::string host = dbrow[col]; col++; - std::string port = dbrow[col]; col++; - std::string path = dbrow[col]; col++; + std::string protocol = dbrow[col]; col++; + std::string method = dbrow[col]; col++; + std::string host = dbrow[col]; col++; + std::string port = dbrow[col]; col++; + std::string path = dbrow[col]; col++; - int width = atoi(dbrow[col]); col++; - int height = atoi(dbrow[col]); col++; - int colours = atoi(dbrow[col]); col++; - /* int palette = atoi(dbrow[col]); */ col++; - Orientation orientation = (Orientation)atoi(dbrow[col]); col++; - unsigned int deinterlacing = atoi(dbrow[col]); col++; - bool rtsp_describe = (*dbrow[col] != '0'); col++; - int savejpegs = atoi(dbrow[col]); col++; - int videowriter = atoi(dbrow[col]); col++; - std::string encoderparams = dbrow[col]; col++; - bool record_audio = (*dbrow[col] != '0'); col++; - - int brightness = atoi(dbrow[col]); col++; - int contrast = atoi(dbrow[col]); col++; - int hue = atoi(dbrow[col]); col++; - int colour = atoi(dbrow[col]); col++; + int width = atoi(dbrow[col]); col++; + int height = atoi(dbrow[col]); col++; + int colours = atoi(dbrow[col]); col++; + /* int palette = atoi(dbrow[col]); */ col++; + Orientation orientation = (Orientation)atoi(dbrow[col]); col++; + unsigned int deinterlacing = atoi(dbrow[col]); col++; + bool rtsp_describe = (*dbrow[col] != '0'); col++; + int savejpegs = atoi(dbrow[col]); col++; + int videowriter = atoi(dbrow[col]); col++; + std::string encoderparams = dbrow[col]; col++; + bool record_audio = (*dbrow[col] != '0'); col++; + + int brightness = atoi(dbrow[col]); col++; + int contrast = atoi(dbrow[col]); col++; + int hue = atoi(dbrow[col]); col++; + int colour = atoi(dbrow[col]); col++; - std::string event_prefix = dbrow[col]; col++; - std::string label_format = dbrow[col]; col++; + std::string event_prefix = dbrow[col]; col++; + std::string label_format = dbrow[col]; col++; - int label_x = atoi(dbrow[col]); col++; - int label_y = atoi(dbrow[col]); col++; - int label_size = atoi(dbrow[col]); col++; + int label_x = atoi(dbrow[col]); col++; + int label_y = atoi(dbrow[col]); col++; + int label_size = atoi(dbrow[col]); col++; - int image_buffer_count = atoi(dbrow[col]); col++; - int warmup_count = atoi(dbrow[col]); col++; - int pre_event_count = atoi(dbrow[col]); col++; - int post_event_count = atoi(dbrow[col]); col++; - int stream_replay_buffer = atoi(dbrow[col]); col++; - int alarm_frame_count = atoi(dbrow[col]); col++; - int section_length = atoi(dbrow[col]); col++; - int frame_skip = atoi(dbrow[col]); col++; - int motion_frame_skip = atoi(dbrow[col]); col++; - double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; - unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); - int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int fps_report_interval = atoi(dbrow[col]); col++; - int ref_blend_perc = atoi(dbrow[col]); col++; - int alarm_ref_blend_perc = atoi(dbrow[col]); col++; - int track_motion = atoi(dbrow[col]); col++; - bool embed_exif = (*dbrow[col] != '0'); col++; + int image_buffer_count = atoi(dbrow[col]); col++; + int warmup_count = atoi(dbrow[col]); col++; + int pre_event_count = atoi(dbrow[col]); col++; + int post_event_count = atoi(dbrow[col]); col++; + int stream_replay_buffer = atoi(dbrow[col]); col++; + int alarm_frame_count = atoi(dbrow[col]); col++; + int section_length = atoi(dbrow[col]); col++; + int frame_skip = atoi(dbrow[col]); col++; + int motion_frame_skip = atoi(dbrow[col]); col++; + double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; + unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); + int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int fps_report_interval = atoi(dbrow[col]); col++; + int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; + int track_motion = atoi(dbrow[col]); col++; + bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); - - Camera *camera = 0; - if ( protocol == "http" ) { - camera = new RemoteCameraHttp( - id, - method, - host, // Host - port, // Port - path, // Path - cam_width, - cam_height, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); - } + Camera *camera = 0; + if ( protocol == "http" ) { + camera = new RemoteCameraHttp( + id, + method, + host, // Host + port, // Port + path, // Path + width, + height, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); + } #if HAVE_LIBAVFORMAT - else if ( protocol == "rtsp" ) { - camera = new RemoteCameraRtsp( - id, - method, - host, // Host - port, // Port - path, // Path - cam_width, - cam_height, - rtsp_describe, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); - } + else if ( protocol == "rtsp" ) { + camera = new RemoteCameraRtsp( + id, + method, + host, // Host + port, // Port + path, // Path + width, + height, + rtsp_describe, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); + } #endif // HAVE_LIBAVFORMAT - else { - Fatal( "Unexpected remote camera protocol '%s'", protocol.c_str() ); - } + else { + Fatal( "Unexpected remote camera protocol '%s'", protocol.c_str() ); + } - monitors[i] = new Monitor( - id, - name.c_str(), - server_id, - storage_id, - function, - enabled, - linked_monitors, - camera, - orientation, - deinterlacing, - savejpegs, - videowriter, - encoderparams, - record_audio, - event_prefix.c_str(), - label_format.c_str(), - Coord( label_x, label_y ), - label_size, - image_buffer_count, - warmup_count, - pre_event_count, - post_event_count, - stream_replay_buffer, - alarm_frame_count, - section_length, - frame_skip, - motion_frame_skip, - analysis_fps, - analysis_update_delay, - capture_delay, - alarm_capture_delay, - fps_report_interval, - ref_blend_perc, - alarm_ref_blend_perc, - track_motion, - RGB_WHITE, - embed_exif, - purpose, - 0, - 0 - ); - Zone **zones = 0; - int n_zones = Zone::Load( monitors[i], zones ); - monitors[i]->AddZones( n_zones, zones ); - monitors[i]->AddPrivacyBitmask( zones ); - Debug( 1, "Loaded monitor %d(%s), %d zones", id, name.c_str(), n_zones ); - } - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - // Yadda yadda - mysql_free_result( result ); + monitors[i] = new Monitor( + id, + name.c_str(), + server_id, + storage_id, + function, + enabled, + linked_monitors, + camera, + orientation, + deinterlacing, + savejpegs, + videowriter, + encoderparams, + record_audio, + event_prefix.c_str(), + label_format.c_str(), + Coord( label_x, label_y ), + label_size, + image_buffer_count, + warmup_count, + pre_event_count, + post_event_count, + stream_replay_buffer, + alarm_frame_count, + section_length, + frame_skip, + motion_frame_skip, + analysis_fps, + analysis_update_delay, + capture_delay, + alarm_capture_delay, + fps_report_interval, + ref_blend_perc, + alarm_ref_blend_perc, + track_motion, + RGB_WHITE, + embed_exif, + purpose, + 0, + 0 + ); + Zone **zones = 0; + int n_zones = Zone::Load( monitors[i], zones ); + monitors[i]->AddZones( n_zones, zones ); + monitors[i]->AddPrivacyBitmask( zones ); + Debug( 1, "Loaded monitor %d(%s), %d zones", id, name.c_str(), n_zones ); + } + if ( mysql_errno( &dbconn ) ) + { + Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + // Yadda yadda + mysql_free_result( result ); - return( n_monitors ); + return( n_monitors ); } int Monitor::LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ) { - std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'File'"; - if ( file[0] ) { - sql += " AND Path='"; - sql += file; - sql += "'"; - } - if ( staticConfig.SERVER_ID ) { - sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID ); - } - Debug( 1, "Loading File Monitors with %s", sql.c_str() ); - MYSQL_RES *result = zmDbFetch( sql.c_str() ); - if ( !result ) { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - int n_monitors = mysql_num_rows( result ); - Debug( 1, "Got %d monitors", n_monitors ); - delete[] monitors; - monitors = new Monitor *[n_monitors]; - for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { - int col = 0; + std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'File'"; + if ( file[0] ) { + sql += " AND Path='"; + sql += file; + sql += "'"; + } + if ( staticConfig.SERVER_ID ) { + sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID ); + } + Debug( 1, "Loading File Monitors with %s", sql.c_str() ); + MYSQL_RES *result = zmDbFetch( sql.c_str() ); + if ( !result ) { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + int n_monitors = mysql_num_rows( result ); + Debug( 1, "Got %d monitors", n_monitors ); + delete[] monitors; + monitors = new Monitor *[n_monitors]; + for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { + int col = 0; - int id = atoi(dbrow[col]); col++; - const char *name = dbrow[col]; col++; - unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - int function = atoi(dbrow[col]); col++; - int enabled = atoi(dbrow[col]); col++; - const char *linked_monitors = dbrow[col]; col++; + int id = atoi(dbrow[col]); col++; + const char *name = dbrow[col]; col++; + unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + int function = atoi(dbrow[col]); col++; + int enabled = atoi(dbrow[col]); col++; + const char *linked_monitors = dbrow[col]; col++; - const char *path = dbrow[col]; col++; + const char *path = dbrow[col]; col++; - int width = atoi(dbrow[col]); col++; - int height = atoi(dbrow[col]); col++; - int colours = atoi(dbrow[col]); col++; - /* int palette = atoi(dbrow[col]); */ col++; - Orientation orientation = (Orientation)atoi(dbrow[col]); col++; - unsigned int deinterlacing = atoi(dbrow[col]); col++; + int width = atoi(dbrow[col]); col++; + int height = atoi(dbrow[col]); col++; + int colours = atoi(dbrow[col]); col++; + /* int palette = atoi(dbrow[col]); */ col++; + Orientation orientation = (Orientation)atoi(dbrow[col]); col++; + unsigned int deinterlacing = atoi(dbrow[col]); col++; - int savejpegs = atoi(dbrow[col]); col++; - int videowriter = atoi(dbrow[col]); col++; - std::string encoderparams = dbrow[col]; col++; - bool record_audio = (*dbrow[col] != '0'); col++; + int savejpegs = atoi(dbrow[col]); col++; + int videowriter = atoi(dbrow[col]); col++; + std::string encoderparams = dbrow[col]; col++; + bool record_audio = (*dbrow[col] != '0'); col++; - int brightness = atoi(dbrow[col]); col++; - int contrast = atoi(dbrow[col]); col++; - int hue = atoi(dbrow[col]); col++; - int colour = atoi(dbrow[col]); col++; + int brightness = atoi(dbrow[col]); col++; + int contrast = atoi(dbrow[col]); col++; + int hue = atoi(dbrow[col]); col++; + int colour = atoi(dbrow[col]); col++; - const char *event_prefix = dbrow[col]; col++; - const char *label_format = dbrow[col]; col++; + const char *event_prefix = dbrow[col]; col++; + const char *label_format = dbrow[col]; col++; - int label_x = atoi(dbrow[col]); col++; - int label_y = atoi(dbrow[col]); col++; - int label_size = atoi(dbrow[col]); col++; + int label_x = atoi(dbrow[col]); col++; + int label_y = atoi(dbrow[col]); col++; + int label_size = atoi(dbrow[col]); col++; - int image_buffer_count = atoi(dbrow[col]); col++; - int warmup_count = atoi(dbrow[col]); col++; - int pre_event_count = atoi(dbrow[col]); col++; - int post_event_count = atoi(dbrow[col]); col++; - int stream_replay_buffer = atoi(dbrow[col]); col++; - int alarm_frame_count = atoi(dbrow[col]); col++; - int section_length = atoi(dbrow[col]); col++; - int frame_skip = atoi(dbrow[col]); col++; - int motion_frame_skip = atoi(dbrow[col]); col++; - double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; - unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); - int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int fps_report_interval = atoi(dbrow[col]); col++; - int ref_blend_perc = atoi(dbrow[col]); col++; - int alarm_ref_blend_perc = atoi(dbrow[col]); col++; - int track_motion = atoi(dbrow[col]); col++; - bool embed_exif = (*dbrow[col] != '0'); col++; + int image_buffer_count = atoi(dbrow[col]); col++; + int warmup_count = atoi(dbrow[col]); col++; + int pre_event_count = atoi(dbrow[col]); col++; + int post_event_count = atoi(dbrow[col]); col++; + int stream_replay_buffer = atoi(dbrow[col]); col++; + int alarm_frame_count = atoi(dbrow[col]); col++; + int section_length = atoi(dbrow[col]); col++; + int frame_skip = atoi(dbrow[col]); col++; + int motion_frame_skip = atoi(dbrow[col]); col++; + double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; + unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); + int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int fps_report_interval = atoi(dbrow[col]); col++; + int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; + int track_motion = atoi(dbrow[col]); col++; + bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); + Camera *camera = new FileCamera( + id, + path, // File + width, + height, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); - Camera *camera = new FileCamera( - id, - path, // File - cam_width, - cam_height, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); + monitors[i] = new Monitor( + id, + name, + server_id, + storage_id, + function, + enabled, + linked_monitors, + camera, + orientation, + deinterlacing, + savejpegs, + videowriter, + encoderparams, + record_audio, + event_prefix, + label_format, + Coord( label_x, label_y ), + label_size, + image_buffer_count, + warmup_count, + pre_event_count, + post_event_count, + stream_replay_buffer, + alarm_frame_count, + section_length, + frame_skip, + motion_frame_skip, + analysis_fps, + analysis_update_delay, + capture_delay, + alarm_capture_delay, + fps_report_interval, + ref_blend_perc, + alarm_ref_blend_perc, + track_motion, + embed_exif, + RGB_WHITE, + purpose, + 0, + 0 + ); + Zone **zones = 0; + int n_zones = Zone::Load( monitors[i], zones ); + monitors[i]->AddZones( n_zones, zones ); + monitors[i]->AddPrivacyBitmask( zones ); + Debug( 1, "Loaded monitor %d(%s), %d zones", id, name, n_zones ); + } + if ( mysql_errno( &dbconn ) ) + { + Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + // Yadda yadda + mysql_free_result( result ); - monitors[i] = new Monitor( - id, - name, - server_id, - storage_id, - function, - enabled, - linked_monitors, - camera, - orientation, - deinterlacing, - savejpegs, - videowriter, - encoderparams, - record_audio, - event_prefix, - label_format, - Coord( label_x, label_y ), - label_size, - image_buffer_count, - warmup_count, - pre_event_count, - post_event_count, - stream_replay_buffer, - alarm_frame_count, - section_length, - frame_skip, - motion_frame_skip, - analysis_fps, - analysis_update_delay, - capture_delay, - alarm_capture_delay, - fps_report_interval, - ref_blend_perc, - alarm_ref_blend_perc, - track_motion, - embed_exif, - RGB_WHITE, - purpose, - 0, - 0 - ); - Zone **zones = 0; - int n_zones = Zone::Load( monitors[i], zones ); - monitors[i]->AddZones( n_zones, zones ); - monitors[i]->AddPrivacyBitmask( zones ); - Debug( 1, "Loaded monitor %d(%s), %d zones", id, name, n_zones ); - } - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - // Yadda yadda - mysql_free_result( result ); - - return( n_monitors ); + return( n_monitors ); } #if HAVE_LIBAVFORMAT int Monitor::LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose purpose ) { - std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Method, Options, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Ffmpeg'"; - if ( file[0] ) { - sql += " AND Path = '"; - sql += file; - sql += "'"; - } - if ( staticConfig.SERVER_ID ) { - sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID ); - } - Debug( 1, "Loading FFMPEG Monitors with %s", sql.c_str() ); - MYSQL_RES *result = zmDbFetch( sql.c_str() ); - if ( ! result ) { - Error( "Cannot load FfmpegMonitors" ); - exit( mysql_errno( &dbconn ) ); - } + std::string sql = "select Id, Name, ServerId, StorageId, Function+0, Enabled, LinkedMonitors, Path, Method, Options, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif from Monitors where Function != 'None' and Type = 'Ffmpeg'"; + if ( file[0] ) { + sql += " AND Path = '"; + sql += file; + sql += "'"; + } + if ( staticConfig.SERVER_ID ) { + sql += stringtf( " AND ServerId=%d", staticConfig.SERVER_ID ); + } + Debug( 1, "Loading FFMPEG Monitors with %s", sql.c_str() ); + MYSQL_RES *result = zmDbFetch( sql.c_str() ); + if ( ! result ) { + Error( "Cannot load FfmpegMonitors" ); + exit( mysql_errno( &dbconn ) ); + } - int n_monitors = mysql_num_rows( result ); - Debug( 1, "Got %d monitors", n_monitors ); - delete[] monitors; - monitors = new Monitor *[n_monitors]; - for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { - int col = 0; + int n_monitors = mysql_num_rows( result ); + Debug( 1, "Got %d monitors", n_monitors ); + delete[] monitors; + monitors = new Monitor *[n_monitors]; + for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) { + int col = 0; - int id = atoi(dbrow[col]); col++; - const char *name = dbrow[col]; col++; - unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - int function = atoi(dbrow[col]); col++; - int enabled = atoi(dbrow[col]); col++; - const char *linked_monitors = dbrow[col]; col++; + int id = atoi(dbrow[col]); col++; + const char *name = dbrow[col]; col++; + unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + int function = atoi(dbrow[col]); col++; + int enabled = atoi(dbrow[col]); col++; + const char *linked_monitors = dbrow[col]; col++; - const char *path = dbrow[col]; col++; - const char *method = dbrow[col]; col++; - const char *options = dbrow[col]; col++; + const char *path = dbrow[col]; col++; + const char *method = dbrow[col]; col++; + const char *options = dbrow[col]; col++; - int width = atoi(dbrow[col]); col++; - int height = atoi(dbrow[col]); col++; - int colours = atoi(dbrow[col]); col++; - /* int palette = atoi(dbrow[col]); */ col++; - Orientation orientation = (Orientation)atoi(dbrow[col]); col++; - unsigned int deinterlacing = atoi(dbrow[col]); col++; + int width = atoi(dbrow[col]); col++; + int height = atoi(dbrow[col]); col++; + int colours = atoi(dbrow[col]); col++; + /* int palette = atoi(dbrow[col]); */ col++; + Orientation orientation = (Orientation)atoi(dbrow[col]); col++; + unsigned int deinterlacing = atoi(dbrow[col]); col++; - int savejpegs = atoi(dbrow[col]); col++; - int videowriter = atoi(dbrow[col]); col++; - std::string encoderparams = dbrow[col]; col++; - bool record_audio = (*dbrow[col] != '0'); col++; + int savejpegs = atoi(dbrow[col]); col++; + int videowriter = atoi(dbrow[col]); col++; + std::string encoderparams = dbrow[col]; col++; + bool record_audio = (*dbrow[col] != '0'); col++; - int brightness = atoi(dbrow[col]); col++; - int contrast = atoi(dbrow[col]); col++; - int hue = atoi(dbrow[col]); col++; - int colour = atoi(dbrow[col]); col++; + int brightness = atoi(dbrow[col]); col++; + int contrast = atoi(dbrow[col]); col++; + int hue = atoi(dbrow[col]); col++; + int colour = atoi(dbrow[col]); col++; - const char *event_prefix = dbrow[col]; col++; - const char *label_format = dbrow[col]; col++; + const char *event_prefix = dbrow[col]; col++; + const char *label_format = dbrow[col]; col++; - int label_x = atoi(dbrow[col]); col++; - int label_y = atoi(dbrow[col]); col++; - int label_size = atoi(dbrow[col]); col++; + int label_x = atoi(dbrow[col]); col++; + int label_y = atoi(dbrow[col]); col++; + int label_size = atoi(dbrow[col]); col++; - int image_buffer_count = atoi(dbrow[col]); col++; - int warmup_count = atoi(dbrow[col]); col++; - int pre_event_count = atoi(dbrow[col]); col++; - int post_event_count = atoi(dbrow[col]); col++; - int stream_replay_buffer = atoi(dbrow[col]); col++; - int alarm_frame_count = atoi(dbrow[col]); col++; - int section_length = atoi(dbrow[col]); col++; - int frame_skip = atoi(dbrow[col]); col++; - int motion_frame_skip = atoi(dbrow[col]); col++; - double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; - unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); - int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int fps_report_interval = atoi(dbrow[col]); col++; - int ref_blend_perc = atoi(dbrow[col]); col++; - int alarm_ref_blend_perc = atoi(dbrow[col]); col++; - int track_motion = atoi(dbrow[col]); col++; - bool embed_exif = (*dbrow[col] != '0'); col++; + int image_buffer_count = atoi(dbrow[col]); col++; + int warmup_count = atoi(dbrow[col]); col++; + int pre_event_count = atoi(dbrow[col]); col++; + int post_event_count = atoi(dbrow[col]); col++; + int stream_replay_buffer = atoi(dbrow[col]); col++; + int alarm_frame_count = atoi(dbrow[col]); col++; + int section_length = atoi(dbrow[col]); col++; + int frame_skip = atoi(dbrow[col]); col++; + int motion_frame_skip = atoi(dbrow[col]); col++; + double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; + unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); + int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int fps_report_interval = atoi(dbrow[col]); col++; + int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; + int track_motion = atoi(dbrow[col]); col++; + bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); + Camera *camera = new FfmpegCamera( + id, + path, // File + method, + options, + width, + height, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); - Camera *camera = new FfmpegCamera( - id, - path, // File - method, - options, - cam_width, - cam_height, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); + monitors[i] = new Monitor( + id, + name, + server_id, + storage_id, + function, + enabled, + linked_monitors, + camera, + orientation, + deinterlacing, + savejpegs, + videowriter, + encoderparams, + record_audio, + event_prefix, + label_format, + Coord( label_x, label_y ), + label_size, + image_buffer_count, + warmup_count, + pre_event_count, + post_event_count, + stream_replay_buffer, + alarm_frame_count, + section_length, + frame_skip, + motion_frame_skip, + analysis_fps, + analysis_update_delay, + capture_delay, + alarm_capture_delay, + fps_report_interval, + ref_blend_perc, + alarm_ref_blend_perc, + track_motion, + embed_exif, + RGB_WHITE, + purpose, + 0, + 0 + ); + Zone **zones = 0; + int n_zones = Zone::Load( monitors[i], zones ); + monitors[i]->AddZones( n_zones, zones ); + monitors[i]->AddPrivacyBitmask( zones ); + Debug( 1, "Loaded monitor %d(%s), %d zones", id, name, n_zones ); + } + if ( mysql_errno( &dbconn ) ) + { + Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + // Yadda yadda + mysql_free_result( result ); - monitors[i] = new Monitor( - id, - name, - server_id, - storage_id, - function, - enabled, - linked_monitors, - camera, - orientation, - deinterlacing, - savejpegs, - videowriter, - encoderparams, - record_audio, - event_prefix, - label_format, - Coord( label_x, label_y ), - label_size, - image_buffer_count, - warmup_count, - pre_event_count, - post_event_count, - stream_replay_buffer, - alarm_frame_count, - section_length, - frame_skip, - motion_frame_skip, - analysis_fps, - analysis_update_delay, - capture_delay, - alarm_capture_delay, - fps_report_interval, - ref_blend_perc, - alarm_ref_blend_perc, - track_motion, - embed_exif, - RGB_WHITE, - purpose, - 0, - 0 - ); - Zone **zones = 0; - int n_zones = Zone::Load( monitors[i], zones ); - monitors[i]->AddZones( n_zones, zones ); - monitors[i]->AddPrivacyBitmask( zones ); - Debug( 1, "Loaded monitor %d(%s), %d zones", id, name, n_zones ); - } - if ( mysql_errno( &dbconn ) ) - { - Error( "Can't fetch row: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - // Yadda yadda - mysql_free_result( result ); - - return( n_monitors ); + return( n_monitors ); } #endif // HAVE_LIBAVFORMAT Monitor *Monitor::Load( unsigned int p_id, bool load_zones, Purpose purpose ) { - std::string sql = stringtf( "select Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id ); + std::string sql = stringtf( "select Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, Protocol, Method, Host, Port, Path, Options, User, Pass, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, RTSPDescribe, SaveJPEGs, VideoWriter, EncoderParameters, RecordAudio, Brightness, Contrast, Hue, Colour, EventPrefix, LabelFormat, LabelX, LabelY, LabelSize, ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, SectionLength, FrameSkip, MotionFrameSkip, AnalysisFPS, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, SignalCheckColour, Exif from Monitors where Id = %d", p_id ); - MYSQL_ROW dbrow = zmDbFetchOne( sql.c_str() ); - if ( ! dbrow ) { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - Monitor *monitor = 0; - unsigned int col = 0; + zmDbRow dbrow; + if ( ! dbrow.fetch( sql.c_str() ) ) { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + Monitor *monitor = 0; + unsigned int col = 0; - unsigned int id = atoi(dbrow[col]); col++; - std::string name = dbrow[col]; col++; - unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; - std::string type = dbrow[col]; col++; - int function = atoi(dbrow[col]); col++; - int enabled = atoi(dbrow[col]); col++; - std::string linked_monitors = dbrow[col]; col++; + unsigned int id = atoi(dbrow[col]); col++; + std::string name = dbrow[col]; col++; + unsigned int server_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + unsigned int storage_id = dbrow[col] ? atoi(dbrow[col]) : 0; col++; + std::string type = dbrow[col]; col++; + int function = atoi(dbrow[col]); col++; + int enabled = atoi(dbrow[col]); col++; + std::string linked_monitors = dbrow[col]; col++; - std::string device = dbrow[col]; col++; - int channel = atoi(dbrow[col]); col++; - int format = atoi(dbrow[col]); col++; + std::string device = dbrow[col]; col++; + int channel = atoi(dbrow[col]); col++; + int format = atoi(dbrow[col]); col++; - bool v4l_multi_buffer = config.v4l_multi_buffer; - if ( dbrow[col] ) { - if (*dbrow[col] == '0' ) { - v4l_multi_buffer = false; - } else if ( *dbrow[col] == '1' ) { - v4l_multi_buffer = true; - } - } - col++; + bool v4l_multi_buffer = config.v4l_multi_buffer; + if ( dbrow[col] ) { + if (*dbrow[col] == '0' ) { + v4l_multi_buffer = false; + } else if ( *dbrow[col] == '1' ) { + v4l_multi_buffer = true; + } + } + col++; - int v4l_captures_per_frame = 0; - if ( dbrow[col] ) { - v4l_captures_per_frame = atoi(dbrow[col]); - } else { - v4l_captures_per_frame = config.captures_per_frame; - } - Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); - col++; + int v4l_captures_per_frame = 0; + if ( dbrow[col] ) { + v4l_captures_per_frame = atoi(dbrow[col]); + } else { + v4l_captures_per_frame = config.captures_per_frame; + } + Debug( 1, "Got %d for v4l_captures_per_frame", v4l_captures_per_frame ); + col++; - std::string protocol = dbrow[col]; col++; - std::string method = dbrow[col]; col++; - std::string host = dbrow[col]; col++; - std::string port = dbrow[col]; col++; - std::string path = dbrow[col]; col++; - std::string options = dbrow[col]; col++; - std::string user = dbrow[col]; col++; - std::string pass = dbrow[col]; col++; + std::string protocol = dbrow[col]; col++; + std::string method = dbrow[col]; col++; + std::string host = dbrow[col]; col++; + std::string port = dbrow[col]; col++; + std::string path = dbrow[col]; col++; + std::string options = dbrow[col]; col++; + std::string user = dbrow[col]; col++; + std::string pass = dbrow[col]; col++; - int width = atoi(dbrow[col]); col++; - int height = atoi(dbrow[col]); col++; - int colours = atoi(dbrow[col]); col++; - int palette = atoi(dbrow[col]); col++; - Orientation orientation = (Orientation)atoi(dbrow[col]); col++; - unsigned int deinterlacing = atoi(dbrow[col]); col++; - bool rtsp_describe = (*dbrow[col] != '0'); col++; - int savejpegs = atoi(dbrow[col]); col++; - int videowriter = atoi(dbrow[col]); col++; - std::string encoderparams = dbrow[col]; col++; - bool record_audio = (*dbrow[col] != '0'); col++; + int width = atoi(dbrow[col]); col++; + int height = atoi(dbrow[col]); col++; + int colours = atoi(dbrow[col]); col++; + int palette = atoi(dbrow[col]); col++; + Orientation orientation = (Orientation)atoi(dbrow[col]); col++; + unsigned int deinterlacing = atoi(dbrow[col]); col++; + bool rtsp_describe = (*dbrow[col] != '0'); col++; + int savejpegs = atoi(dbrow[col]); col++; + int videowriter = atoi(dbrow[col]); col++; + std::string encoderparams = dbrow[col]; col++; + bool record_audio = (*dbrow[col] != '0'); col++; - int brightness = atoi(dbrow[col]); col++; - int contrast = atoi(dbrow[col]); col++; - int hue = atoi(dbrow[col]); col++; - int colour = atoi(dbrow[col]); col++; + int brightness = atoi(dbrow[col]); col++; + int contrast = atoi(dbrow[col]); col++; + int hue = atoi(dbrow[col]); col++; + int colour = atoi(dbrow[col]); col++; - std::string event_prefix = dbrow[col]; col++; - std::string label_format = dbrow[col]; col++; + std::string event_prefix = dbrow[col]; col++; + std::string label_format = dbrow[col]; col++; - int label_x = atoi(dbrow[col]); col++; - int label_y = atoi(dbrow[col]); col++; - int label_size = atoi(dbrow[col]); col++; + int label_x = atoi(dbrow[col]); col++; + int label_y = atoi(dbrow[col]); col++; + int label_size = atoi(dbrow[col]); col++; - int image_buffer_count = atoi(dbrow[col]); col++; - int warmup_count = atoi(dbrow[col]); col++; - int pre_event_count = atoi(dbrow[col]); col++; - int post_event_count = atoi(dbrow[col]); col++; - int stream_replay_buffer = atoi(dbrow[col]); col++; - int alarm_frame_count = atoi(dbrow[col]); col++; - int section_length = atoi(dbrow[col]); col++; - int frame_skip = atoi(dbrow[col]); col++; - int motion_frame_skip = atoi(dbrow[col]); col++; - double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; - unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); - int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; - int fps_report_interval = atoi(dbrow[col]); col++; - int ref_blend_perc = atoi(dbrow[col]); col++; - int alarm_ref_blend_perc = atoi(dbrow[col]); col++; - int track_motion = atoi(dbrow[col]); col++; + int image_buffer_count = atoi(dbrow[col]); col++; + int warmup_count = atoi(dbrow[col]); col++; + int pre_event_count = atoi(dbrow[col]); col++; + int post_event_count = atoi(dbrow[col]); col++; + int stream_replay_buffer = atoi(dbrow[col]); col++; + int alarm_frame_count = atoi(dbrow[col]); col++; + int section_length = atoi(dbrow[col]); col++; + int frame_skip = atoi(dbrow[col]); col++; + int motion_frame_skip = atoi(dbrow[col]); col++; + double analysis_fps = dbrow[col] ? strtod(dbrow[col], NULL) : 0; col++; + unsigned int analysis_update_delay = strtoul(dbrow[col++], NULL, 0); + int capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int alarm_capture_delay = (dbrow[col]&&atof(dbrow[col])>0.0)?int(DT_PREC_3/atof(dbrow[col])):0; col++; + int fps_report_interval = atoi(dbrow[col]); col++; + int ref_blend_perc = atoi(dbrow[col]); col++; + int alarm_ref_blend_perc = atoi(dbrow[col]); col++; + int track_motion = atoi(dbrow[col]); col++; - int signal_check_colour; - if ( dbrow[col][0] == '#' ) - signal_check_colour = strtol(dbrow[col]+1,0,16); - else - signal_check_colour = strtol(dbrow[col],0,16); - col++; - bool embed_exif = (*dbrow[col] != '0'); col++; + int signal_check_colour; + if ( dbrow[col][0] == '#' ) + signal_check_colour = strtol(dbrow[col]+1,0,16); + else + signal_check_colour = strtol(dbrow[col],0,16); + col++; + bool embed_exif = (*dbrow[col] != '0'); col++; - int cam_width = ((orientation==ROTATE_90||orientation==ROTATE_270)?height:width); - int cam_height = ((orientation==ROTATE_90||orientation==ROTATE_270)?width:height); + int extras = (deinterlacing>>24)&0xff; - int extras = (deinterlacing>>24)&0xff; - - Camera *camera = 0; - if ( type == "Local" ) { + Camera *camera = 0; + if ( type == "Local" ) { #if ZM_HAS_V4L - camera = new LocalCamera( - id, - device.c_str(), - channel, - format, - v4l_multi_buffer, - v4l_captures_per_frame, - method, - cam_width, - cam_height, - colours, - palette, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio, - extras - ); + camera = new LocalCamera( + id, + device.c_str(), + channel, + format, + v4l_multi_buffer, + v4l_captures_per_frame, + method, + width, + height, + colours, + palette, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio, + extras + ); #else // ZM_HAS_V4L - Fatal( "You must have video4linux libraries and headers installed to use local analog or USB cameras for monitor %d", id ); + Fatal( "You must have video4linux libraries and headers installed to use local analog or USB cameras for monitor %d", id ); #endif // ZM_HAS_V4L - } else if ( type == "Remote" ) { - if ( protocol == "http" ) { - camera = new RemoteCameraHttp( - id, - method.c_str(), - host.c_str(), - port.c_str(), - path.c_str(), - cam_width, - cam_height, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); - } else if ( protocol == "rtsp" ) { + } else if ( type == "Remote" ) { + if ( protocol == "http" ) { + camera = new RemoteCameraHttp( + id, + method.c_str(), + host.c_str(), + port.c_str(), + path.c_str(), + width, + height, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); + } else if ( protocol == "rtsp" ) { #if HAVE_LIBAVFORMAT - camera = new RemoteCameraRtsp( - id, - method.c_str(), - host.c_str(), - port.c_str(), - path.c_str(), - cam_width, - cam_height, - rtsp_describe, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); + camera = new RemoteCameraRtsp( + id, + method.c_str(), + host.c_str(), + port.c_str(), + path.c_str(), + width, + height, + rtsp_describe, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); #else // HAVE_LIBAVFORMAT - Fatal( "You must have ffmpeg libraries installed to use remote camera protocol '%s' for monitor %d", protocol.c_str(), id ); + Fatal( "You must have ffmpeg libraries installed to use remote camera protocol '%s' for monitor %d", protocol.c_str(), id ); #endif // HAVE_LIBAVFORMAT - } else { - Fatal( "Unexpected remote camera protocol '%s' for monitor %d", protocol.c_str(), id ); - } - } else if ( type == "File" ) { - camera = new FileCamera( - id, - path.c_str(), - cam_width, - cam_height, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); - } else if ( type == "Ffmpeg" ) { + } else { + Fatal( "Unexpected remote camera protocol '%s' for monitor %d", protocol.c_str(), id ); + } + } else if ( type == "File" ) { + camera = new FileCamera( + id, + path.c_str(), + width, + height, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); + } else if ( type == "Ffmpeg" ) { #if HAVE_LIBAVFORMAT - camera = new FfmpegCamera( - id, - path.c_str(), - method, - options, - cam_width, - cam_height, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); + camera = new FfmpegCamera( + id, + path.c_str(), + method, + options, + width, + height, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); #else // HAVE_LIBAVFORMAT - Fatal( "You must have ffmpeg libraries installed to use ffmpeg cameras for monitor %d", id ); + Fatal( "You must have ffmpeg libraries installed to use ffmpeg cameras for monitor %d", id ); #endif // HAVE_LIBAVFORMAT - } else if (type == "Libvlc") { + } else if (type == "Libvlc") { #if HAVE_LIBVLC - camera = new LibvlcCamera( - id, - path.c_str(), - method, - options, - cam_width, - cam_height, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); + camera = new LibvlcCamera( + id, + path.c_str(), + method, + options, + width, + height, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); #else // HAVE_LIBVLC - Fatal( "You must have vlc libraries installed to use vlc cameras for monitor %d", id ); + Fatal( "You must have vlc libraries installed to use vlc cameras for monitor %d", id ); #endif // HAVE_LIBVLC - } else if ( type == "cURL" ) { + } else if ( type == "cURL" ) { #if HAVE_LIBCURL - camera = new cURLCamera( - id, - path.c_str(), - user.c_str(), - pass.c_str(), - cam_width, - cam_height, - colours, - brightness, - contrast, - hue, - colour, - purpose==CAPTURE, - record_audio - ); + camera = new cURLCamera( + id, + path.c_str(), + user.c_str(), + pass.c_str(), + width, + height, + colours, + brightness, + contrast, + hue, + colour, + purpose==CAPTURE, + record_audio + ); #else // HAVE_LIBCURL - Fatal( "You must have libcurl installed to use ffmpeg cameras for monitor %d", id ); + Fatal( "You must have libcurl installed to use ffmpeg cameras for monitor %d", id ); #endif // HAVE_LIBCURL - } else { - Fatal( "Bogus monitor type '%s' for monitor %d", type.c_str(), id ); - } - monitor = new Monitor( - id, - name.c_str(), - server_id, - storage_id, - function, - enabled, - linked_monitors.c_str(), - camera, - orientation, - deinterlacing, - savejpegs, - videowriter, - encoderparams, - record_audio, - event_prefix.c_str(), - label_format.c_str(), - Coord( label_x, label_y ), - label_size, - image_buffer_count, - warmup_count, - pre_event_count, - post_event_count, - stream_replay_buffer, - alarm_frame_count, - section_length, - frame_skip, - motion_frame_skip, - analysis_fps, - analysis_update_delay, - capture_delay, - alarm_capture_delay, - fps_report_interval, - ref_blend_perc, - alarm_ref_blend_perc, - track_motion, - signal_check_colour, - embed_exif, - purpose, - 0, - 0 + } else { + Fatal( "Bogus monitor type '%s' for monitor %d", type.c_str(), id ); + } + monitor = new Monitor( + id, + name.c_str(), + server_id, + storage_id, + function, + enabled, + linked_monitors.c_str(), + camera, + orientation, + deinterlacing, + savejpegs, + videowriter, + encoderparams, + record_audio, + event_prefix.c_str(), + label_format.c_str(), + Coord( label_x, label_y ), + label_size, + image_buffer_count, + warmup_count, + pre_event_count, + post_event_count, + stream_replay_buffer, + alarm_frame_count, + section_length, + frame_skip, + motion_frame_skip, + analysis_fps, + analysis_update_delay, + capture_delay, + alarm_capture_delay, + fps_report_interval, + ref_blend_perc, + alarm_ref_blend_perc, + track_motion, + signal_check_colour, + embed_exif, + purpose, + 0, + 0 - ); + ); - int n_zones = 0; - if ( load_zones ) { - Zone **zones = 0; - n_zones = Zone::Load( monitor, zones ); - monitor->AddZones( n_zones, zones ); - monitor->AddPrivacyBitmask( zones ); - } - Debug( 1, "Loaded monitor %d(%s), %d zones", id, name.c_str(), n_zones ); - return( monitor ); + int n_zones = 0; + if ( load_zones ) { + Zone **zones = 0; + n_zones = Zone::Load( monitor, zones ); + monitor->AddZones( n_zones, zones ); + monitor->AddPrivacyBitmask( zones ); + } + Debug( 1, "Loaded monitor %d(%s), %d zones", id, name.c_str(), n_zones ); + return( monitor ); } int Monitor::Capture() { - static int FirstCapture = 1; - int captureResult; + static int FirstCapture = 1; + int captureResult; - int index = image_count%image_buffer_count; - Image* capture_image = image_buffer[index].image; + int index = image_count%image_buffer_count; + Image* capture_image = image_buffer[index].image; - if ( (deinterlacing & 0xff) == 4) { - if ( FirstCapture != 1 ) { - /* Copy the next image into the shared memory */ - capture_image->CopyBuffer(*(next_buffer.image)); - } - - /* Capture a new next image */ - - //Check if FFMPEG camera - if((GetOptVideoWriter() == 2) && camera->SupportsNativeVideo()){ - captureResult = camera->CaptureAndRecord(*(next_buffer.image), video_store_data->recording, video_store_data->event_file); - }else{ - captureResult = camera->Capture(*(next_buffer.image)); - } + if ( (deinterlacing & 0xff) == 4) { + if ( FirstCapture != 1 ) { + /* Copy the next image into the shared memory */ + capture_image->CopyBuffer(*(next_buffer.image)); + } + + /* Capture a new next image */ + + //Check if FFMPEG camera + if((GetOptVideoWriter() == 2) && camera->SupportsNativeVideo()){ + captureResult = camera->CaptureAndRecord(*(next_buffer.image), video_store_data->recording, video_store_data->event_file); + }else{ + captureResult = camera->Capture(*(next_buffer.image)); + } - if ( FirstCapture ) { - FirstCapture = 0; - return 0; - } + if ( FirstCapture ) { + FirstCapture = 0; + return 0; + } - } else { - //Check if FFMPEG camera - if((GetOptVideoWriter() == 2) && camera->SupportsNativeVideo()){ - //Warning("ZMC: Recording: %d", video_store_data->recording); - captureResult = camera->CaptureAndRecord(*capture_image, video_store_data->recording, video_store_data->event_file); - }else{ - /* Capture directly into image buffer, avoiding the need to memcpy() */ - captureResult = camera->Capture(*capture_image); - } - } - - if((GetOptVideoWriter() == 2) && captureResult > 0){ - //video_store_data->frameNumber = captureResult; - captureResult = 0; - } - - if ( captureResult != 0 ) { - // Unable to capture image for temporary reason - // Fake a signal loss image - Rgb signalcolor; - signalcolor = rgb_convert(signal_check_colour, ZM_SUBPIX_ORDER_BGR); /* HTML colour code is actually BGR in memory, we want RGB */ - capture_image->Fill(signalcolor); - captureResult = 0; - } else { - captureResult = 1; - } - - if ( captureResult == 1 ) { - - /* Deinterlacing */ - if ( (deinterlacing & 0xff) == 1 ) { - capture_image->Deinterlace_Discard(); - } else if ( (deinterlacing & 0xff) == 2 ) { - capture_image->Deinterlace_Linear(); - } else if ( (deinterlacing & 0xff) == 3 ) { - capture_image->Deinterlace_Blend(); - } else if ( (deinterlacing & 0xff) == 4 ) { - capture_image->Deinterlace_4Field( next_buffer.image, (deinterlacing>>8)&0xff ); - } else if ( (deinterlacing & 0xff) == 5 ) { - capture_image->Deinterlace_Blend_CustomRatio( (deinterlacing>>8)&0xff ); - } - - - if ( orientation != ROTATE_0 ) { - switch ( orientation ) { - case ROTATE_0 : { - // No action required - break; - } - case ROTATE_90 : - case ROTATE_180 : - case ROTATE_270 : { - capture_image->Rotate( (orientation-1)*90 ); - break; - } - case FLIP_HORI : - case FLIP_VERT : { - capture_image->Flip( orientation==FLIP_HORI ); - break; - } - } - } - } // end if captureResults == 1 + } else { + //Check if FFMPEG camera + if((GetOptVideoWriter() == 2) && camera->SupportsNativeVideo()){ + //Warning("ZMC: Recording: %d", video_store_data->recording); + captureResult = camera->CaptureAndRecord(*capture_image, video_store_data->recording, video_store_data->event_file); + }else{ + /* Capture directly into image buffer, avoiding the need to memcpy() */ + captureResult = camera->Capture(*capture_image); + } + } + + if((GetOptVideoWriter() == 2) && captureResult > 0){ + //video_store_data->frameNumber = captureResult; + captureResult = 0; + } + + if ( captureResult != 0 ) { + // Unable to capture image for temporary reason + // Fake a signal loss image + Rgb signalcolor; + signalcolor = rgb_convert(signal_check_colour, ZM_SUBPIX_ORDER_BGR); /* HTML colour code is actually BGR in memory, we want RGB */ + capture_image->Fill(signalcolor); + captureResult = 0; + } else { + captureResult = 1; + } + + if ( captureResult == 1 ) { + + /* Deinterlacing */ + if ( (deinterlacing & 0xff) == 1 ) { + capture_image->Deinterlace_Discard(); + } else if ( (deinterlacing & 0xff) == 2 ) { + capture_image->Deinterlace_Linear(); + } else if ( (deinterlacing & 0xff) == 3 ) { + capture_image->Deinterlace_Blend(); + } else if ( (deinterlacing & 0xff) == 4 ) { + capture_image->Deinterlace_4Field( next_buffer.image, (deinterlacing>>8)&0xff ); + } else if ( (deinterlacing & 0xff) == 5 ) { + capture_image->Deinterlace_Blend_CustomRatio( (deinterlacing>>8)&0xff ); + } + + + if ( orientation != ROTATE_0 ) { + switch ( orientation ) { + case ROTATE_0 : { + // No action required + break; + } + case ROTATE_90 : + case ROTATE_180 : + case ROTATE_270 : { + capture_image->Rotate( (orientation-1)*90 ); + break; + } + case FLIP_HORI : + case FLIP_VERT : { + capture_image->Flip( orientation==FLIP_HORI ); + break; + } + } + } + } // end if captureResults == 1 - // if true? let's get rid of this. - if ( true ) { + // if true? let's get rid of this. + if ( true ) { - if ( capture_image->Size() > camera->ImageSize() ) { - Error( "Captured image %d does not match expected size %d check width, height and colour depth",capture_image->Size(),camera->ImageSize() ); - return( -1 ); - } + if ( capture_image->Size() > camera->ImageSize() ) { + Error( "Captured image %d does not match expected size %d check width, height and colour depth",capture_image->Size(),camera->ImageSize() ); + return( -1 ); + } - if ( ((unsigned int)index == shared_data->last_read_index) && (function > MONITOR) ) { - Warning( "Buffer overrun at index %d, image %d, slow down capture, speed up analysis or increase ring buffer size", index, image_count ); - time_t now = time(0); - double approxFps = double(image_buffer_count)/double(now-image_buffer[index].timestamp->tv_sec); - time_t last_read_delta = now - shared_data->last_read_time; - if ( last_read_delta > (image_buffer_count/approxFps) ) { - Warning( "Last image read from shared memory %ld seconds ago, zma may have gone away", last_read_delta ) - shared_data->last_read_index = image_buffer_count; - } - } + if ( ((unsigned int)index == shared_data->last_read_index) && (function > MONITOR) ) { + Warning( "Buffer overrun at index %d, image %d, slow down capture, speed up analysis or increase ring buffer size", index, image_count ); + time_t now = time(0); + double approxFps = double(image_buffer_count)/double(now-image_buffer[index].timestamp->tv_sec); + time_t last_read_delta = now - shared_data->last_read_time; + if ( last_read_delta > (image_buffer_count/approxFps) ) { + Warning( "Last image read from shared memory %ld seconds ago, zma may have gone away", last_read_delta ) + shared_data->last_read_index = image_buffer_count; + } + } - if ( privacy_bitmask ) - capture_image->MaskPrivacy( privacy_bitmask ); + if ( privacy_bitmask ) + capture_image->MaskPrivacy( privacy_bitmask ); - gettimeofday( image_buffer[index].timestamp, NULL ); - if ( config.timestamp_on_capture ) { - TimestampImage( capture_image, image_buffer[index].timestamp ); - } - shared_data->signal = CheckSignal(capture_image); - shared_data->last_write_index = index; - shared_data->last_write_time = image_buffer[index].timestamp->tv_sec; + gettimeofday( image_buffer[index].timestamp, NULL ); + if ( config.timestamp_on_capture ) { + TimestampImage( capture_image, image_buffer[index].timestamp ); + } + shared_data->signal = CheckSignal(capture_image); + shared_data->last_write_index = index; + shared_data->last_write_time = image_buffer[index].timestamp->tv_sec; - image_count++; + image_count++; - if ( image_count && fps_report_interval && !(image_count%fps_report_interval) ) { - time_t now = image_buffer[index].timestamp->tv_sec; - fps = double(fps_report_interval)/(now-last_fps_time); - //Info( "%d -> %d -> %d", fps_report_interval, now, last_fps_time ); - //Info( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps ); - Info( "%s: %d - Capturing at %.2lf fps", name, image_count, fps ); - last_fps_time = now; - } + if ( image_count && fps_report_interval && !(image_count%fps_report_interval) ) { + time_t now = image_buffer[index].timestamp->tv_sec; + fps = double(fps_report_interval)/(now-last_fps_time); + //Info( "%d -> %d -> %d", fps_report_interval, now, last_fps_time ); + //Info( "%d -> %d -> %lf -> %lf", now-last_fps_time, fps_report_interval/(now-last_fps_time), double(fps_report_interval)/(now-last_fps_time), fps ); + Info( "%s: %d - Capturing at %.2lf fps", name, image_count, fps ); + last_fps_time = now; + } - if ( shared_data->action & GET_SETTINGS ) { - shared_data->brightness = camera->Brightness(); - shared_data->hue = camera->Hue(); - shared_data->colour = camera->Colour(); - shared_data->contrast = camera->Contrast(); - shared_data->action &= ~GET_SETTINGS; - } - if ( shared_data->action & SET_SETTINGS ) { - camera->Brightness( shared_data->brightness ); - camera->Hue( shared_data->hue ); - camera->Colour( shared_data->colour ); - camera->Contrast( shared_data->contrast ); - shared_data->action &= ~SET_SETTINGS; - } - return( 0 ); - } - shared_data->signal = false; - return( -1 ); + if ( shared_data->action & GET_SETTINGS ) { + shared_data->brightness = camera->Brightness(); + shared_data->hue = camera->Hue(); + shared_data->colour = camera->Colour(); + shared_data->contrast = camera->Contrast(); + shared_data->action &= ~GET_SETTINGS; + } + if ( shared_data->action & SET_SETTINGS ) { + camera->Brightness( shared_data->brightness ); + camera->Hue( shared_data->hue ); + camera->Colour( shared_data->colour ); + camera->Contrast( shared_data->contrast ); + shared_data->action &= ~SET_SETTINGS; + } + return( 0 ); + } + shared_data->signal = false; + return( -1 ); } void Monitor::TimestampImage( Image *ts_image, const struct timeval *ts_time ) const { - if ( label_format[0] ) - { - // Expand the strftime macros first - char label_time_text[256]; - strftime( label_time_text, sizeof(label_time_text), label_format, localtime( &ts_time->tv_sec ) ); + if ( label_format[0] ) + { + // Expand the strftime macros first + char label_time_text[256]; + strftime( label_time_text, sizeof(label_time_text), label_format, localtime( &ts_time->tv_sec ) ); - char label_text[1024]; - const char *s_ptr = label_time_text; - char *d_ptr = label_text; - while ( *s_ptr && ((d_ptr-label_text) < (unsigned int)sizeof(label_text)) ) - { - if ( *s_ptr == '%' ) - { - bool found_macro = false; - switch ( *(s_ptr+1) ) - { - case 'N' : - d_ptr += snprintf( d_ptr, sizeof(label_text)-(d_ptr-label_text), "%s", name ); - found_macro = true; - break; - case 'Q' : - d_ptr += snprintf( d_ptr, sizeof(label_text)-(d_ptr-label_text), "%s", trigger_data->trigger_showtext ); - found_macro = true; - break; - case 'f' : - d_ptr += snprintf( d_ptr, sizeof(label_text)-(d_ptr-label_text), "%02ld", ts_time->tv_usec/10000 ); - found_macro = true; - break; - } - if ( found_macro ) - { - s_ptr += 2; - continue; - } - } - *d_ptr++ = *s_ptr++; - } - *d_ptr = '\0'; - ts_image->Annotate( label_text, label_coord, label_size ); - } + char label_text[1024]; + const char *s_ptr = label_time_text; + char *d_ptr = label_text; + while ( *s_ptr && ((d_ptr-label_text) < (unsigned int)sizeof(label_text)) ) + { + if ( *s_ptr == '%' ) + { + bool found_macro = false; + switch ( *(s_ptr+1) ) + { + case 'N' : + d_ptr += snprintf( d_ptr, sizeof(label_text)-(d_ptr-label_text), "%s", name ); + found_macro = true; + break; + case 'Q' : + d_ptr += snprintf( d_ptr, sizeof(label_text)-(d_ptr-label_text), "%s", trigger_data->trigger_showtext ); + found_macro = true; + break; + case 'f' : + d_ptr += snprintf( d_ptr, sizeof(label_text)-(d_ptr-label_text), "%02ld", ts_time->tv_usec/10000 ); + found_macro = true; + break; + } + if ( found_macro ) + { + s_ptr += 2; + continue; + } + } + *d_ptr++ = *s_ptr++; + } + *d_ptr = '\0'; + ts_image->Annotate( label_text, label_coord, label_size ); + } } bool Monitor::closeEvent() { - video_store_data->recording = false; - if ( event ) { - if ( function == RECORD || function == MOCORD ) { - gettimeofday( &(event->EndTime()), NULL ); - } - delete event; - event = 0; - return( true ); - } - return( false ); + video_store_data->recording = false; + if ( event ) { + if ( function == RECORD || function == MOCORD ) { + gettimeofday( &(event->EndTime()), NULL ); + } + delete event; + event = 0; + return( true ); + } + return( false ); } -//----------------------------------------- - -/* - * NOTE Nextime's comment: - * - * OurCheckAlarms seems to be called only by DetectBlack method, and DetectBlack - * method is only called in a commented line instead of DetectMotion in zm_monitor.cpp. - * - * Probably this is just a dead code used for debugghing purpose, so, instead of fixing it - * it seems to be safe to just comment it out. - * - * Anyway, the issues with this code is that it assumes the image to be an RGB24 image, - * so, as i've discussed on IRC with mastertheknife, changes needed are: - * - * Check if the image is 24 or 32 bits ( pImage->Colours() says 3 for 24 and 4 for 32 bits, - * comparing it with ZM_COLOUR_RGB24 or ZM_COLOUR_RGB32 is the way ), and then - * manage che check using RGB_VAL_RED() and so on macros instead of just RED(). - * - * Be careful that in 32 bit images we need to check also where the alpha channel is, so, - * (RGBA and BGRA) or (ABGR and ARGB) aren't the same! - * - * To check black pixels in 32 bit images i can do a more efficient way using - * RGBA_ZERO_ALPHA(pixel) == RGBA_ZERO_ALPHA(RGB_BLACK), but before of that i need to - * check where the alpha channel is and maybe convert it. - * Maybe this won't work as they assign "23" to black_thr, so, they are not checking - * if the pixel is black, but just "quasi" black is enough. - * - * Anyway, for the moment, comment out whole part. - */ - -/* -bool Monitor::OurCheckAlarms( Zone *zone, const Image *pImage ) -{ - Info("Entering OurCheckAlarms >>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - unsigned char black_thr = 23; - int min_alarm_score = 10; - int max_alarm_score = 99; - //bool alarm = false; - unsigned int score; - Polygon zone_polygon = zone->GetPolygon(); - Info("Got polygon of a zone. It has %d vertices.", zone_polygon.getNumCoords()); - - zone->ResetStats(); - Info("ResetStats done."); - - if ( !zone->CheckOverloadCount() ) - { - Info("CheckOverloadCount() return false, we'll return false."); - return( false ); - } - - Image *pMaskImage = new Image(pImage->Width(), pImage->Height(), ZM_COLOUR_GRAY8, pImage->SubpixelOrder()); - Info("Mask image created."); - - pMaskImage->Fill(BLACK); - Info("Mask image filled with BLACK."); - if (pImage->Colours() == ZM_COLOUR_GRAY8) - { - Info("Analysed image is not colored! Set score = 0."); - score = 0; - } - else - { - Info("Start processing image."); - //Process image - unsigned char *buffer = (unsigned char*)pImage->Buffer(); - unsigned char *mask_buffer = (unsigned char*)pMaskImage->Buffer(); - - int black_pixels_count = 0; - Info("Loop for black pixels counting and mask filling."); - while (buffer < (pImage->Buffer() + pImage->Size())) - { - if ( (RED(buffer) < black_thr) && (GREEN(buffer) < black_thr) && (BLUE(buffer) < black_thr) ) - { - *mask_buffer = WHITE; - black_pixels_count++; - } - buffer += pImage->Colours(); - mask_buffer++; - } - - if ( !black_pixels_count ) - { - delete pMaskImage; - return( false ); - } - score = (100*black_pixels_count)/zone_polygon.Area(); - Info("Number of black pixels is %d, zone polygon area is %d, score is %d", black_pixels_count, zone_polygon.Area(), score); - - if ( min_alarm_score && ( score < min_alarm_score) ) - { - delete pMaskImage; - return( false ); - } - if ( max_alarm_score && (score > max_alarm_score) ) - { - zone->SetOverloadCount(zone->GetOverloadFrames()); - delete pMaskImage; - return( false ); - } - } - - zone->SetScore(score); - Info("Score have been set in zone."); - //Get mask - Rgb alarm_colour = RGB_RED; - Image *tempImage = pMaskImage->HighlightEdges(alarm_colour, &zone_polygon.Extent() ); - Info("After HighlightEdges"); - - zone->SetAlarmImage(tempImage); - Info("After SetAlarmImage"); - delete pMaskImage; - Info("After Delete pMaskImage"); - delete tempImage; - - Info("Leaving OurCheckAlarms >>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - return true; -} - -unsigned int Monitor::DetectBlack(const Image &comp_image, Event::StringSet &zoneSet ) -{ - Info("Entering DetectBlack >>>>>>>>>>>>>>>>>>>>>>>>>>"); - bool alarm = false; - unsigned int score = 0; - - if ( n_zones <= 0 ) return( alarm ); - -// Coord alarm_centre; -// int top_score = -1; - - // Find all alarm pixels in active zones - Info("Number of zones to process %d", n_zones); - for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) - { - Zone *zone = zones[n_zone]; - if ( !zone->IsActive() ) - { - continue; - } - Debug( 3, "Checking active zone %s", zone->Label() ); - Info( "Checking active zone %s", zone->Label() ); - if ( OurCheckAlarms( zone, &comp_image ) ) - { - Info("OurCheckAlarm is TRUE!!!!!!"); - alarm = true; - score += zone->Score(); - zone->SetAlarm(); - Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() ); - Info( "Zone is alarmed, zone score = %d", zone->Score() ); - zoneSet.insert( zone->Label() ); -// if ( config.opt_control && track_motion ) -// { -// if ( (int)zone->Score() > top_score ) -// { -// top_score = zone->Score(); -// alarm_centre = zone->GetAlarmCentre(); -// } -// } - } - Info( "Finish checking active zone %s", zone->Label() ); - } - - -// if ( top_score > 0 ) -// { -// shared_data->alarm_x = alarm_centre.X(); -// shared_data->alarm_y = alarm_centre.Y(); -// -// Info( "Got alarm centre at %d,%d, at count %d", shared_data->alarm_x, shared_data->alarm_y, image_count ); -// } -// else -// { -// shared_data->alarm_x = shared_data->alarm_y = -1; -// } - - // This is a small and innocent hack to prevent scores of 0 being returned in alarm state - Info("Leaving DetectBlack <<<<<<<<<<<<<<<<<<<<<<<<<<<"); - return( score?score:alarm ); -} - -*/ -//----------------------------------------------------------------------------------------------- - - - unsigned int Monitor::DetectMotion( const Image &comp_image, Event::StringSet &zoneSet ) { - bool alarm = false; - unsigned int score = 0; + bool alarm = false; + unsigned int score = 0; - if ( n_zones <= 0 ) return( alarm ); + if ( n_zones <= 0 ) return( alarm ); - Storage *storage = this->getStorage(); + Storage *storage = this->getStorage(); - if ( config.record_diag_images ) - { - static char diag_path[PATH_MAX] = ""; - if ( !diag_path[0] ) - { - snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-r.jpg", storage->Path(), id ); - } - ref_image.WriteJpeg( diag_path ); - } + if ( config.record_diag_images ) + { + static char diag_path[PATH_MAX] = ""; + if ( !diag_path[0] ) + { + snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-r.jpg", storage->Path(), id ); + } + ref_image.WriteJpeg( diag_path ); + } - ref_image.Delta( comp_image, &delta_image); + ref_image.Delta( comp_image, &delta_image); - if ( config.record_diag_images ) - { - static char diag_path[PATH_MAX] = ""; - if ( !diag_path[0] ) - { - snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-d.jpg", storage->Path(), id ); - } - delta_image.WriteJpeg( diag_path ); - } + if ( config.record_diag_images ) + { + static char diag_path[PATH_MAX] = ""; + if ( !diag_path[0] ) + { + snprintf( diag_path, sizeof(diag_path), "%s/%d/diag-d.jpg", storage->Path(), id ); + } + delta_image.WriteJpeg( diag_path ); + } - // Blank out all exclusion zones - for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) - { - Zone *zone = zones[n_zone]; - // need previous alarmed state for preclusive zone, so don't clear just yet - if (!zone->IsPreclusive()) - zone->ClearAlarm(); - if ( !zone->IsInactive() ) - { - continue; - } - Debug( 3, "Blanking inactive zone %s", zone->Label() ); - delta_image.Fill( RGB_BLACK, zone->GetPolygon() ); - } + // Blank out all exclusion zones + for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) + { + Zone *zone = zones[n_zone]; + // need previous alarmed state for preclusive zone, so don't clear just yet + if (!zone->IsPreclusive()) + zone->ClearAlarm(); + if ( !zone->IsInactive() ) + { + continue; + } + Debug( 3, "Blanking inactive zone %s", zone->Label() ); + delta_image.Fill( RGB_BLACK, zone->GetPolygon() ); + } - // Check preclusive zones first - for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) - { - Zone *zone = zones[n_zone]; - if ( !zone->IsPreclusive() ) - { - continue; - } - int old_zone_score = zone->Score(); - bool old_zone_alarmed = zone->Alarmed(); - Debug( 3, "Checking preclusive zone %s - old score: %d, state: %s", zone->Label(),old_zone_score, zone->Alarmed()?"alarmed":"quiet" ); - if ( zone->CheckAlarms( &delta_image ) ) - { - alarm = true; - score += zone->Score(); - zone->SetAlarm(); - Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() ); - zoneSet.insert( zone->Label() ); - //zone->ResetStats(); - } else { - // check if end of alarm - if (old_zone_alarmed) { - Debug(3, "Preclusive Zone %s alarm Ends. Prevíous score: %d", zone->Label(), old_zone_score); - if (old_zone_score > 0) { - zone->SetExtendAlarmCount(zone->GetExtendAlarmFrames()); - } - if (zone->CheckExtendAlarmCount()) { - alarm=true; - zone->SetAlarm(); - } else { - zone->ClearAlarm(); - } - } - } - } + // Check preclusive zones first + for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) + { + Zone *zone = zones[n_zone]; + if ( !zone->IsPreclusive() ) + { + continue; + } + int old_zone_score = zone->Score(); + bool old_zone_alarmed = zone->Alarmed(); + Debug( 3, "Checking preclusive zone %s - old score: %d, state: %s", zone->Label(),old_zone_score, zone->Alarmed()?"alarmed":"quiet" ); + if ( zone->CheckAlarms( &delta_image ) ) + { + alarm = true; + score += zone->Score(); + zone->SetAlarm(); + Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() ); + zoneSet.insert( zone->Label() ); + //zone->ResetStats(); + } else { + // check if end of alarm + if (old_zone_alarmed) { + Debug(3, "Preclusive Zone %s alarm Ends. Prevíous score: %d", zone->Label(), old_zone_score); + if (old_zone_score > 0) { + zone->SetExtendAlarmCount(zone->GetExtendAlarmFrames()); + } + if (zone->CheckExtendAlarmCount()) { + alarm=true; + zone->SetAlarm(); + } else { + zone->ClearAlarm(); + } + } + } + } - Coord alarm_centre; - int top_score = -1; + Coord alarm_centre; + int top_score = -1; - if ( alarm ) - { - alarm = false; - score = 0; - } - else - { - // Find all alarm pixels in active zones - for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) - { - Zone *zone = zones[n_zone]; - if ( !zone->IsActive() || zone->IsPreclusive()) - { - continue; - } - Debug( 3, "Checking active zone %s", zone->Label() ); - if ( zone->CheckAlarms( &delta_image ) ) - { - alarm = true; - score += zone->Score(); - zone->SetAlarm(); - Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() ); - zoneSet.insert( zone->Label() ); - if ( config.opt_control && track_motion ) - { - if ( (int)zone->Score() > top_score ) - { - top_score = zone->Score(); - alarm_centre = zone->GetAlarmCentre(); - } - } - } - } + if ( alarm ) + { + alarm = false; + score = 0; + } + else + { + // Find all alarm pixels in active zones + for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) + { + Zone *zone = zones[n_zone]; + if ( !zone->IsActive() || zone->IsPreclusive()) + { + continue; + } + Debug( 3, "Checking active zone %s", zone->Label() ); + if ( zone->CheckAlarms( &delta_image ) ) + { + alarm = true; + score += zone->Score(); + zone->SetAlarm(); + Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() ); + zoneSet.insert( zone->Label() ); + if ( config.opt_control && track_motion ) + { + if ( (int)zone->Score() > top_score ) + { + top_score = zone->Score(); + alarm_centre = zone->GetAlarmCentre(); + } + } + } + } - if ( alarm ) - { - for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) - { - Zone *zone = zones[n_zone]; - if ( !zone->IsInclusive() ) - { - continue; - } - Debug( 3, "Checking inclusive zone %s", zone->Label() ); - if ( zone->CheckAlarms( &delta_image ) ) - { - alarm = true; - score += zone->Score(); - zone->SetAlarm(); - Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() ); - zoneSet.insert( zone->Label() ); - if ( config.opt_control && track_motion ) - { - if ( zone->Score() > (unsigned int)top_score ) - { - top_score = zone->Score(); - alarm_centre = zone->GetAlarmCentre(); - } - } - } - } - } - else - { - // Find all alarm pixels in exclusive zones - for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) - { - Zone *zone = zones[n_zone]; - if ( !zone->IsExclusive() ) - { - continue; - } - Debug( 3, "Checking exclusive zone %s", zone->Label() ); - if ( zone->CheckAlarms( &delta_image ) ) - { - alarm = true; - score += zone->Score(); - zone->SetAlarm(); - Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() ); - zoneSet.insert( zone->Label() ); - } - } - } - } + if ( alarm ) + { + for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) + { + Zone *zone = zones[n_zone]; + if ( !zone->IsInclusive() ) + { + continue; + } + Debug( 3, "Checking inclusive zone %s", zone->Label() ); + if ( zone->CheckAlarms( &delta_image ) ) + { + alarm = true; + score += zone->Score(); + zone->SetAlarm(); + Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() ); + zoneSet.insert( zone->Label() ); + if ( config.opt_control && track_motion ) + { + if ( zone->Score() > (unsigned int)top_score ) + { + top_score = zone->Score(); + alarm_centre = zone->GetAlarmCentre(); + } + } + } + } + } + else + { + // Find all alarm pixels in exclusive zones + for ( int n_zone = 0; n_zone < n_zones; n_zone++ ) + { + Zone *zone = zones[n_zone]; + if ( !zone->IsExclusive() ) + { + continue; + } + Debug( 3, "Checking exclusive zone %s", zone->Label() ); + if ( zone->CheckAlarms( &delta_image ) ) + { + alarm = true; + score += zone->Score(); + zone->SetAlarm(); + Debug( 3, "Zone is alarmed, zone score = %d", zone->Score() ); + zoneSet.insert( zone->Label() ); + } + } + } + } - if ( top_score > 0 ) - { - shared_data->alarm_x = alarm_centre.X(); - shared_data->alarm_y = alarm_centre.Y(); + if ( top_score > 0 ) + { + shared_data->alarm_x = alarm_centre.X(); + shared_data->alarm_y = alarm_centre.Y(); - Info( "Got alarm centre at %d,%d, at count %d", shared_data->alarm_x, shared_data->alarm_y, image_count ); - } - else - { - shared_data->alarm_x = shared_data->alarm_y = -1; - } + Info( "Got alarm centre at %d,%d, at count %d", shared_data->alarm_x, shared_data->alarm_y, image_count ); + } + else + { + shared_data->alarm_x = shared_data->alarm_y = -1; + } - // This is a small and innocent hack to prevent scores of 0 being returned in alarm state - return( score?score:alarm ); + // This is a small and innocent hack to prevent scores of 0 being returned in alarm state + return( score?score:alarm ); } bool Monitor::DumpSettings( char *output, bool verbose ) { - output[0] = 0; + output[0] = 0; - sprintf( output+strlen(output), "Id : %d\n", id ); - sprintf( output+strlen(output), "Name : %s\n", name ); - sprintf( output+strlen(output), "Type : %s\n", camera->IsLocal()?"Local":(camera->IsRemote()?"Remote":"File") ); + sprintf( output+strlen(output), "Id : %d\n", id ); + sprintf( output+strlen(output), "Name : %s\n", name ); + sprintf( output+strlen(output), "Type : %s\n", camera->IsLocal()?"Local":(camera->IsRemote()?"Remote":"File") ); #if ZM_HAS_V4L - if ( camera->IsLocal() ) - { - sprintf( output+strlen(output), "Device : %s\n", ((LocalCamera *)camera)->Device().c_str() ); - sprintf( output+strlen(output), "Channel : %d\n", ((LocalCamera *)camera)->Channel() ); - sprintf( output+strlen(output), "Standard : %d\n", ((LocalCamera *)camera)->Standard() ); - } - else + if ( camera->IsLocal() ) + { + sprintf( output+strlen(output), "Device : %s\n", ((LocalCamera *)camera)->Device().c_str() ); + sprintf( output+strlen(output), "Channel : %d\n", ((LocalCamera *)camera)->Channel() ); + sprintf( output+strlen(output), "Standard : %d\n", ((LocalCamera *)camera)->Standard() ); + } + else #endif // ZM_HAS_V4L - if ( camera->IsRemote() ) - { - sprintf( output+strlen(output), "Protocol : %s\n", ((RemoteCamera *)camera)->Protocol().c_str() ); - sprintf( output+strlen(output), "Host : %s\n", ((RemoteCamera *)camera)->Host().c_str() ); - sprintf( output+strlen(output), "Port : %s\n", ((RemoteCamera *)camera)->Port().c_str() ); - sprintf( output+strlen(output), "Path : %s\n", ((RemoteCamera *)camera)->Path().c_str() ); - } - else if ( camera->IsFile() ) - { - sprintf( output+strlen(output), "Path : %s\n", ((FileCamera *)camera)->Path() ); - } + if ( camera->IsRemote() ) + { + sprintf( output+strlen(output), "Protocol : %s\n", ((RemoteCamera *)camera)->Protocol().c_str() ); + sprintf( output+strlen(output), "Host : %s\n", ((RemoteCamera *)camera)->Host().c_str() ); + sprintf( output+strlen(output), "Port : %s\n", ((RemoteCamera *)camera)->Port().c_str() ); + sprintf( output+strlen(output), "Path : %s\n", ((RemoteCamera *)camera)->Path().c_str() ); + } + else if ( camera->IsFile() ) + { + sprintf( output+strlen(output), "Path : %s\n", ((FileCamera *)camera)->Path() ); + } #if HAVE_LIBAVFORMAT - else if ( camera->IsFfmpeg() ) - { - sprintf( output+strlen(output), "Path : %s\n", ((FfmpegCamera *)camera)->Path().c_str() ); - } + else if ( camera->IsFfmpeg() ) + { + sprintf( output+strlen(output), "Path : %s\n", ((FfmpegCamera *)camera)->Path().c_str() ); + } #endif // HAVE_LIBAVFORMAT - sprintf( output+strlen(output), "Width : %d\n", camera->Width() ); - sprintf( output+strlen(output), "Height : %d\n", camera->Height() ); + sprintf( output+strlen(output), "Width : %d\n", camera->Width() ); + sprintf( output+strlen(output), "Height : %d\n", camera->Height() ); #if ZM_HAS_V4L - if ( camera->IsLocal() ) - { - sprintf( output+strlen(output), "Palette : %d\n", ((LocalCamera *)camera)->Palette() ); - } + if ( camera->IsLocal() ) + { + sprintf( output+strlen(output), "Palette : %d\n", ((LocalCamera *)camera)->Palette() ); + } #endif // ZM_HAS_V4L - sprintf( output+strlen(output), "Colours : %d\n", camera->Colours() ); - sprintf( output+strlen(output), "Subpixel Order : %d\n", camera->SubpixelOrder() ); - sprintf( output+strlen(output), "Event Prefix : %s\n", event_prefix ); - sprintf( output+strlen(output), "Label Format : %s\n", label_format ); - sprintf( output+strlen(output), "Label Coord : %d,%d\n", label_coord.X(), label_coord.Y() ); - sprintf( output+strlen(output), "Label Size : %d\n", label_size ); - sprintf( output+strlen(output), "Image Buffer Count : %d\n", image_buffer_count ); - sprintf( output+strlen(output), "Warmup Count : %d\n", warmup_count ); - sprintf( output+strlen(output), "Pre Event Count : %d\n", pre_event_count ); - sprintf( output+strlen(output), "Post Event Count : %d\n", post_event_count ); - sprintf( output+strlen(output), "Stream Replay Buffer : %d\n", stream_replay_buffer ); - sprintf( output+strlen(output), "Alarm Frame Count : %d\n", alarm_frame_count ); - sprintf( output+strlen(output), "Section Length : %d\n", section_length ); - sprintf( output+strlen(output), "Maximum FPS : %.2f\n", capture_delay?DT_PREC_3/capture_delay:0.0 ); - sprintf( output+strlen(output), "Alarm Maximum FPS : %.2f\n", alarm_capture_delay?DT_PREC_3/alarm_capture_delay:0.0 ); - sprintf( output+strlen(output), "Reference Blend %%ge : %d\n", ref_blend_perc ); - sprintf( output+strlen(output), "Alarm Reference Blend %%ge : %d\n", alarm_ref_blend_perc ); - sprintf( output+strlen(output), "Track Motion : %d\n", track_motion ); - sprintf( output+strlen(output), "Function: %d - %s\n", function, - function==NONE?"None":( - function==MONITOR?"Monitor Only":( - function==MODECT?"Motion Detection":( - function==RECORD?"Continuous Record":( - function==MOCORD?"Continuous Record with Motion Detection":( - function==NODECT?"Externally Triggered only, no Motion Detection":"Unknown" - )))))); - sprintf( output+strlen(output), "Zones : %d\n", n_zones ); - for ( int i = 0; i < n_zones; i++ ) - { - zones[i]->DumpSettings( output+strlen(output), verbose ); - } - return( true ); + sprintf( output+strlen(output), "Colours : %d\n", camera->Colours() ); + sprintf( output+strlen(output), "Subpixel Order : %d\n", camera->SubpixelOrder() ); + sprintf( output+strlen(output), "Event Prefix : %s\n", event_prefix ); + sprintf( output+strlen(output), "Label Format : %s\n", label_format ); + sprintf( output+strlen(output), "Label Coord : %d,%d\n", label_coord.X(), label_coord.Y() ); + sprintf( output+strlen(output), "Label Size : %d\n", label_size ); + sprintf( output+strlen(output), "Image Buffer Count : %d\n", image_buffer_count ); + sprintf( output+strlen(output), "Warmup Count : %d\n", warmup_count ); + sprintf( output+strlen(output), "Pre Event Count : %d\n", pre_event_count ); + sprintf( output+strlen(output), "Post Event Count : %d\n", post_event_count ); + sprintf( output+strlen(output), "Stream Replay Buffer : %d\n", stream_replay_buffer ); + sprintf( output+strlen(output), "Alarm Frame Count : %d\n", alarm_frame_count ); + sprintf( output+strlen(output), "Section Length : %d\n", section_length ); + sprintf( output+strlen(output), "Maximum FPS : %.2f\n", capture_delay?DT_PREC_3/capture_delay:0.0 ); + sprintf( output+strlen(output), "Alarm Maximum FPS : %.2f\n", alarm_capture_delay?DT_PREC_3/alarm_capture_delay:0.0 ); + sprintf( output+strlen(output), "Reference Blend %%ge : %d\n", ref_blend_perc ); + sprintf( output+strlen(output), "Alarm Reference Blend %%ge : %d\n", alarm_ref_blend_perc ); + sprintf( output+strlen(output), "Track Motion : %d\n", track_motion ); + sprintf( output+strlen(output), "Function: %d - %s\n", function, + function==NONE?"None":( + function==MONITOR?"Monitor Only":( + function==MODECT?"Motion Detection":( + function==RECORD?"Continuous Record":( + function==MOCORD?"Continuous Record with Motion Detection":( + function==NODECT?"Externally Triggered only, no Motion Detection":"Unknown" + )))))); + sprintf( output+strlen(output), "Zones : %d\n", n_zones ); + for ( int i = 0; i < n_zones; i++ ) + { + zones[i]->DumpSettings( output+strlen(output), verbose ); + } + return( true ); } // bool Monitor::DumpSettings( char *output, bool verbose ) bool MonitorStream::checkSwapPath( const char *path, bool create_path ) { - uid_t uid = getuid(); - gid_t gid = getgid(); + uid_t uid = getuid(); + gid_t gid = getgid(); - struct stat stat_buf; - if ( stat( path, &stat_buf ) < 0 ) - { - if ( create_path && errno == ENOENT ) - { - Debug( 3, "Swap path '%s' missing, creating", path ); - if ( mkdir( path, 0755 ) ) - { - Error( "Can't mkdir %s: %s", path, strerror(errno)); - return( false ); - } - if ( stat( path, &stat_buf ) < 0 ) - { - Error( "Can't stat '%s': %s", path, strerror(errno) ); - return( false ); - } - } - else - { - Error( "Can't stat '%s': %s", path, strerror(errno) ); - return( false ); - } - } - if ( !S_ISDIR(stat_buf.st_mode) ) - { - Error( "Swap image path '%s' is not a directory", path ); - return( false ); - } + struct stat stat_buf; + if ( stat( path, &stat_buf ) < 0 ) + { + if ( create_path && errno == ENOENT ) + { + Debug( 3, "Swap path '%s' missing, creating", path ); + if ( mkdir( path, 0755 ) ) + { + Error( "Can't mkdir %s: %s", path, strerror(errno)); + return( false ); + } + if ( stat( path, &stat_buf ) < 0 ) + { + Error( "Can't stat '%s': %s", path, strerror(errno) ); + return( false ); + } + } + else + { + Error( "Can't stat '%s': %s", path, strerror(errno) ); + return( false ); + } + } + if ( !S_ISDIR(stat_buf.st_mode) ) + { + Error( "Swap image path '%s' is not a directory", path ); + return( false ); + } - mode_t mask = 0; - if ( uid == stat_buf.st_uid ) - { - // If we are the owner - mask = 00700; - } - else if ( gid == stat_buf.st_gid ) - { - // If we are in the owner group - mask = 00070; - } - else - { - // We are neither the owner nor in the group - mask = 00007; - } + mode_t mask = 0; + if ( uid == stat_buf.st_uid ) + { + // If we are the owner + mask = 00700; + } + else if ( gid == stat_buf.st_gid ) + { + // If we are in the owner group + mask = 00070; + } + else + { + // We are neither the owner nor in the group + mask = 00007; + } - if ( (stat_buf.st_mode & mask) != mask ) - { - Error( "Insufficient permissions on swap image path '%s'", path ); - return( false ); - } - return( true ); + if ( (stat_buf.st_mode & mask) != mask ) + { + Error( "Insufficient permissions on swap image path '%s'", path ); + return( false ); + } + return( true ); } void MonitorStream::processCommand( const CmdMsg *msg ) { - Debug( 2, "Got message, type %d, msg %d", msg->msg_type, msg->msg_data[0] ); - // Check for incoming command - switch( (MsgCommand)msg->msg_data[0] ) - { - case CMD_PAUSE : - { - Debug( 1, "Got PAUSE command" ); + Debug( 2, "Got message, type %d, msg %d", msg->msg_type, msg->msg_data[0] ); + // Check for incoming command + switch( (MsgCommand)msg->msg_data[0] ) + { + case CMD_PAUSE : + { + Debug( 1, "Got PAUSE command" ); - // Set paused flag - paused = true; - // Set delayed flag - delayed = true; - last_frame_sent = TV_2_FLOAT( now ); - break; - } - case CMD_PLAY : - { - Debug( 1, "Got PLAY command" ); - if ( paused ) - { - // Clear paused flag - paused = false; - // Set delayed_play flag - delayed = true; - } - replay_rate = ZM_RATE_BASE; - break; - } - case CMD_VARPLAY : - { - Debug( 1, "Got VARPLAY command" ); - if ( paused ) - { - // Clear paused flag - paused = false; - // Set delayed_play flag - delayed = true; - } - replay_rate = ntohs(((unsigned char)msg->msg_data[2]<<8)|(unsigned char)msg->msg_data[1])-32768; - break; - } - case CMD_STOP : - { - Debug( 1, "Got STOP command" ); + // Set paused flag + paused = true; + // Set delayed flag + delayed = true; + last_frame_sent = TV_2_FLOAT( now ); + break; + } + case CMD_PLAY : + { + Debug( 1, "Got PLAY command" ); + if ( paused ) + { + // Clear paused flag + paused = false; + // Set delayed_play flag + delayed = true; + } + replay_rate = ZM_RATE_BASE; + break; + } + case CMD_VARPLAY : + { + Debug( 1, "Got VARPLAY command" ); + if ( paused ) + { + // Clear paused flag + paused = false; + // Set delayed_play flag + delayed = true; + } + replay_rate = ntohs(((unsigned char)msg->msg_data[2]<<8)|(unsigned char)msg->msg_data[1])-32768; + break; + } + case CMD_STOP : + { + Debug( 1, "Got STOP command" ); - // Clear paused flag - paused = false; - // Clear delayed_play flag - delayed = false; - break; - } - case CMD_FASTFWD : - { - Debug( 1, "Got FAST FWD command" ); - if ( paused ) - { - // Clear paused flag - paused = false; - // Set delayed_play flag - delayed = true; - } - // Set play rate - switch ( replay_rate ) - { - case 2 * ZM_RATE_BASE : - replay_rate = 5 * ZM_RATE_BASE; - break; - case 5 * ZM_RATE_BASE : - replay_rate = 10 * ZM_RATE_BASE; - break; - case 10 * ZM_RATE_BASE : - replay_rate = 25 * ZM_RATE_BASE; - break; - case 25 * ZM_RATE_BASE : - case 50 * ZM_RATE_BASE : - replay_rate = 50 * ZM_RATE_BASE; - break; - default : - replay_rate = 2 * ZM_RATE_BASE; - break; - } - break; - } - case CMD_SLOWFWD : - { - Debug( 1, "Got SLOW FWD command" ); - // Set paused flag - paused = true; - // Set delayed flag - delayed = true; - // Set play rate - replay_rate = ZM_RATE_BASE; - // Set step - step = 1; - break; - } - case CMD_SLOWREV : - { - Debug( 1, "Got SLOW REV command" ); - // Set paused flag - paused = true; - // Set delayed flag - delayed = true; - // Set play rate - replay_rate = ZM_RATE_BASE; - // Set step - step = -1; - break; - } - case CMD_FASTREV : - { - Debug( 1, "Got FAST REV command" ); - if ( paused ) - { - // Clear paused flag - paused = false; - // Set delayed_play flag - delayed = true; - } - // Set play rate - switch ( replay_rate ) - { - case -2 * ZM_RATE_BASE : - replay_rate = -5 * ZM_RATE_BASE; - break; - case -5 * ZM_RATE_BASE : - replay_rate = -10 * ZM_RATE_BASE; - break; - case -10 * ZM_RATE_BASE : - replay_rate = -25 * ZM_RATE_BASE; - break; - case -25 * ZM_RATE_BASE : - case -50 * ZM_RATE_BASE : - replay_rate = -50 * ZM_RATE_BASE; - break; - default : - replay_rate = -2 * ZM_RATE_BASE; - break; - } - break; - } - case CMD_ZOOMIN : - { - x = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; - y = ((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; - Debug( 1, "Got ZOOM IN command, to %d,%d", x, y ); - switch ( zoom ) - { - case 100: - zoom = 150; - break; - case 150: - zoom = 200; - break; - case 200: - zoom = 300; - break; - case 300: - zoom = 400; - break; - case 400: - default : - zoom = 500; - break; - } - break; - } - case CMD_ZOOMOUT : - { - Debug( 1, "Got ZOOM OUT command" ); - switch ( zoom ) - { - case 500: - zoom = 400; - break; - case 400: - zoom = 300; - break; - case 300: - zoom = 200; - break; - case 200: - zoom = 150; - break; - case 150: - default : - zoom = 100; - break; - } - break; - } - case CMD_PAN : - { - x = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; - y = ((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; - Debug( 1, "Got PAN command, to %d,%d", x, y ); - break; - } - case CMD_SCALE : - { - scale = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; - Debug( 1, "Got SCALE command, to %d", scale ); - break; - } - case CMD_QUIT : - { - Info ("User initiated exit - CMD_QUIT"); - break; - } - case CMD_QUERY : - { - Debug( 1, "Got QUERY command, sending STATUS" ); - break; - } - default : - { - Error( "Got unexpected command %d", msg->msg_data[0] ); - break; - } - } + // Clear paused flag + paused = false; + // Clear delayed_play flag + delayed = false; + break; + } + case CMD_FASTFWD : + { + Debug( 1, "Got FAST FWD command" ); + if ( paused ) + { + // Clear paused flag + paused = false; + // Set delayed_play flag + delayed = true; + } + // Set play rate + switch ( replay_rate ) + { + case 2 * ZM_RATE_BASE : + replay_rate = 5 * ZM_RATE_BASE; + break; + case 5 * ZM_RATE_BASE : + replay_rate = 10 * ZM_RATE_BASE; + break; + case 10 * ZM_RATE_BASE : + replay_rate = 25 * ZM_RATE_BASE; + break; + case 25 * ZM_RATE_BASE : + case 50 * ZM_RATE_BASE : + replay_rate = 50 * ZM_RATE_BASE; + break; + default : + replay_rate = 2 * ZM_RATE_BASE; + break; + } + break; + } + case CMD_SLOWFWD : + { + Debug( 1, "Got SLOW FWD command" ); + // Set paused flag + paused = true; + // Set delayed flag + delayed = true; + // Set play rate + replay_rate = ZM_RATE_BASE; + // Set step + step = 1; + break; + } + case CMD_SLOWREV : + { + Debug( 1, "Got SLOW REV command" ); + // Set paused flag + paused = true; + // Set delayed flag + delayed = true; + // Set play rate + replay_rate = ZM_RATE_BASE; + // Set step + step = -1; + break; + } + case CMD_FASTREV : + { + Debug( 1, "Got FAST REV command" ); + if ( paused ) + { + // Clear paused flag + paused = false; + // Set delayed_play flag + delayed = true; + } + // Set play rate + switch ( replay_rate ) + { + case -2 * ZM_RATE_BASE : + replay_rate = -5 * ZM_RATE_BASE; + break; + case -5 * ZM_RATE_BASE : + replay_rate = -10 * ZM_RATE_BASE; + break; + case -10 * ZM_RATE_BASE : + replay_rate = -25 * ZM_RATE_BASE; + break; + case -25 * ZM_RATE_BASE : + case -50 * ZM_RATE_BASE : + replay_rate = -50 * ZM_RATE_BASE; + break; + default : + replay_rate = -2 * ZM_RATE_BASE; + break; + } + break; + } + case CMD_ZOOMIN : + { + x = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; + y = ((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; + Debug( 1, "Got ZOOM IN command, to %d,%d", x, y ); + switch ( zoom ) + { + case 100: + zoom = 150; + break; + case 150: + zoom = 200; + break; + case 200: + zoom = 300; + break; + case 300: + zoom = 400; + break; + case 400: + default : + zoom = 500; + break; + } + break; + } + case CMD_ZOOMOUT : + { + Debug( 1, "Got ZOOM OUT command" ); + switch ( zoom ) + { + case 500: + zoom = 400; + break; + case 400: + zoom = 300; + break; + case 300: + zoom = 200; + break; + case 200: + zoom = 150; + break; + case 150: + default : + zoom = 100; + break; + } + break; + } + case CMD_PAN : + { + x = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; + y = ((unsigned char)msg->msg_data[3]<<8)|(unsigned char)msg->msg_data[4]; + Debug( 1, "Got PAN command, to %d,%d", x, y ); + break; + } + case CMD_SCALE : + { + scale = ((unsigned char)msg->msg_data[1]<<8)|(unsigned char)msg->msg_data[2]; + Debug( 1, "Got SCALE command, to %d", scale ); + break; + } + case CMD_QUIT : + { + Info ("User initiated exit - CMD_QUIT"); + break; + } + case CMD_QUERY : + { + Debug( 1, "Got QUERY command, sending STATUS" ); + break; + } + default : + { + Error( "Got unexpected command %d", msg->msg_data[0] ); + break; + } + } - struct { - int id; - int state; - double fps; - int buffer_level; - int rate; - double delay; - int zoom; - bool delayed; - bool paused; - bool enabled; - bool forced; - } status_data; + struct { + int id; + int state; + double fps; + int buffer_level; + int rate; + double delay; + int zoom; + bool delayed; + bool paused; + bool enabled; + bool forced; + } status_data; - status_data.id = monitor->Id(); - status_data.fps = monitor->GetFPS(); - status_data.state = monitor->shared_data->state; - if ( playback_buffer > 0 ) - status_data.buffer_level = (MOD_ADD( (temp_write_index-temp_read_index), 0, temp_image_buffer_count )*100)/temp_image_buffer_count; - else - status_data.buffer_level = 0; - status_data.delayed = delayed; - status_data.paused = paused; - status_data.rate = replay_rate; - status_data.delay = TV_2_FLOAT( now ) - TV_2_FLOAT( last_frame_timestamp ); - status_data.zoom = zoom; - //status_data.enabled = monitor->shared_data->active; - status_data.enabled = monitor->trigger_data->trigger_state!=Monitor::TRIGGER_OFF; - status_data.forced = monitor->trigger_data->trigger_state==Monitor::TRIGGER_ON; - Debug( 2, "L:%d, D:%d, P:%d, R:%d, d:%.3f, Z:%d, E:%d F:%d", - status_data.buffer_level, - status_data.delayed, - status_data.paused, - status_data.rate, - status_data.delay, - status_data.zoom, - status_data.enabled, - status_data.forced - ); + status_data.id = monitor->Id(); + status_data.fps = monitor->GetFPS(); + status_data.state = monitor->shared_data->state; + if ( playback_buffer > 0 ) + status_data.buffer_level = (MOD_ADD( (temp_write_index-temp_read_index), 0, temp_image_buffer_count )*100)/temp_image_buffer_count; + else + status_data.buffer_level = 0; + status_data.delayed = delayed; + status_data.paused = paused; + status_data.rate = replay_rate; + status_data.delay = TV_2_FLOAT( now ) - TV_2_FLOAT( last_frame_timestamp ); + status_data.zoom = zoom; + //status_data.enabled = monitor->shared_data->active; + status_data.enabled = monitor->trigger_data->trigger_state!=Monitor::TRIGGER_OFF; + status_data.forced = monitor->trigger_data->trigger_state==Monitor::TRIGGER_ON; + Debug( 2, "L:%d, D:%d, P:%d, R:%d, d:%.3f, Z:%d, E:%d F:%d", + status_data.buffer_level, + status_data.delayed, + status_data.paused, + status_data.rate, + status_data.delay, + status_data.zoom, + status_data.enabled, + status_data.forced + ); - DataMsg status_msg; - status_msg.msg_type = MSG_DATA_WATCH; - memcpy( &status_msg.msg_data, &status_data, sizeof(status_data) ); - int nbytes = 0; - if ( (nbytes = sendto( sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr) )) < 0 ) - { - //if ( errno != EAGAIN ) - { - Error( "Can't sendto on sd %d: %s", sd, strerror(errno) ); - //exit( -1 ); - } - } + DataMsg status_msg; + status_msg.msg_type = MSG_DATA_WATCH; + memcpy( &status_msg.msg_data, &status_data, sizeof(status_data) ); + int nbytes = 0; + if ( (nbytes = sendto( sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr) )) < 0 ) + { + //if ( errno != EAGAIN ) + { + Error( "Can't sendto on sd %d: %s", sd, strerror(errno) ); + //exit( -1 ); + } + } - // quit after sending a status, if this was a quit request - if ((MsgCommand)msg->msg_data[0]==CMD_QUIT) - exit(0); + // quit after sending a status, if this was a quit request + if ((MsgCommand)msg->msg_data[0]==CMD_QUIT) + exit(0); - updateFrameRate( monitor->GetFPS() ); + updateFrameRate( monitor->GetFPS() ); } bool MonitorStream::sendFrame( const char *filepath, struct timeval *timestamp ) { - bool send_raw = ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)); + bool send_raw = ((scale>=ZM_SCALE_BASE)&&(zoom==ZM_SCALE_BASE)); - if ( type != STREAM_JPEG ) - send_raw = false; - if ( !config.timestamp_on_capture && timestamp ) - send_raw = false; + if ( type != STREAM_JPEG ) + send_raw = false; + if ( !config.timestamp_on_capture && timestamp ) + send_raw = false; - if ( !send_raw ) - { - Image temp_image( filepath ); + if ( !send_raw ) + { + Image temp_image( filepath ); - return( sendFrame( &temp_image, timestamp ) ); - } - else - { - int img_buffer_size = 0; - static unsigned char img_buffer[ZM_MAX_IMAGE_SIZE]; + return( sendFrame( &temp_image, timestamp ) ); + } + else + { + int img_buffer_size = 0; + static unsigned char img_buffer[ZM_MAX_IMAGE_SIZE]; - FILE *fdj = NULL; - if ( (fdj = fopen( filepath, "r" )) ) - { - img_buffer_size = fread( img_buffer, 1, sizeof(img_buffer), fdj ); - fclose( fdj ); - } - else - { - Error( "Can't open %s: %s", filepath, strerror(errno) ); - return( false ); - } + FILE *fdj = NULL; + if ( (fdj = fopen( filepath, "r" )) ) + { + img_buffer_size = fread( img_buffer, 1, sizeof(img_buffer), fdj ); + fclose( fdj ); + } + else + { + Error( "Can't open %s: %s", filepath, strerror(errno) ); + return( false ); + } - // Calculate how long it takes to actually send the frame - struct timeval frameStartTime; - gettimeofday( &frameStartTime, NULL ); - - fprintf( stdout, "--ZoneMinderFrame\r\n" ); - fprintf( stdout, "Content-Length: %d\r\n", img_buffer_size ); - fprintf( stdout, "Content-Type: image/jpeg\r\n\r\n" ); - if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) - { - if ( !zm_terminate ) - Error( "Unable to send stream frame: %s", strerror(errno) ); - return( false ); - } - fprintf( stdout, "\r\n\r\n" ); - fflush( stdout ); + // Calculate how long it takes to actually send the frame + struct timeval frameStartTime; + gettimeofday( &frameStartTime, NULL ); + + fprintf( stdout, "--ZoneMinderFrame\r\n" ); + fprintf( stdout, "Content-Length: %d\r\n", img_buffer_size ); + fprintf( stdout, "Content-Type: image/jpeg\r\n\r\n" ); + if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) + { + if ( !zm_terminate ) + Error( "Unable to send stream frame: %s", strerror(errno) ); + return( false ); + } + fprintf( stdout, "\r\n\r\n" ); + fflush( stdout ); - struct timeval frameEndTime; - gettimeofday( &frameEndTime, NULL ); + struct timeval frameEndTime; + gettimeofday( &frameEndTime, NULL ); - int frameSendTime = tvDiffMsec( frameStartTime, frameEndTime ); - if ( frameSendTime > 1000/maxfps ) - { - maxfps /= 2; - Error( "Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps ); - } + int frameSendTime = tvDiffMsec( frameStartTime, frameEndTime ); + if ( frameSendTime > 1000/maxfps ) + { + maxfps /= 2; + Error( "Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps ); + } - last_frame_sent = TV_2_FLOAT( now ); + last_frame_sent = TV_2_FLOAT( now ); - return( true ); - } - return( false ); + return( true ); + } + return( false ); } bool MonitorStream::sendFrame( Image *image, struct timeval *timestamp ) { - Image *send_image = prepareImage( image ); - if ( !config.timestamp_on_capture && timestamp ) - monitor->TimestampImage( send_image, timestamp ); + Image *send_image = prepareImage( image ); + if ( !config.timestamp_on_capture && timestamp ) + monitor->TimestampImage( send_image, timestamp ); #if HAVE_LIBAVCODEC - if ( type == STREAM_MPEG ) - { - if ( !vid_stream ) - { - vid_stream = new VideoStream( "pipe:", format, bitrate, effective_fps, send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height() ); - fprintf( stdout, "Content-type: %s\r\n\r\n", vid_stream->MimeType() ); - vid_stream->OpenStream(); - } - static struct timeval base_time; - struct DeltaTimeval delta_time; - if ( !frame_count ) - base_time = *timestamp; - DELTA_TIMEVAL( delta_time, *timestamp, base_time, DT_PREC_3 ); - /* double pts = */ vid_stream->EncodeFrame( send_image->Buffer(), send_image->Size(), config.mpeg_timed_frames, delta_time.delta ); - } - else + if ( type == STREAM_MPEG ) + { + if ( !vid_stream ) + { + vid_stream = new VideoStream( "pipe:", format, bitrate, effective_fps, send_image->Colours(), send_image->SubpixelOrder(), send_image->Width(), send_image->Height() ); + fprintf( stdout, "Content-type: %s\r\n\r\n", vid_stream->MimeType() ); + vid_stream->OpenStream(); + } + static struct timeval base_time; + struct DeltaTimeval delta_time; + if ( !frame_count ) + base_time = *timestamp; + DELTA_TIMEVAL( delta_time, *timestamp, base_time, DT_PREC_3 ); + /* double pts = */ vid_stream->EncodeFrame( send_image->Buffer(), send_image->Size(), config.mpeg_timed_frames, delta_time.delta ); + } + else #endif // HAVE_LIBAVCODEC - { - static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; + { + static unsigned char temp_img_buffer[ZM_MAX_IMAGE_SIZE]; - int img_buffer_size = 0; - unsigned char *img_buffer = temp_img_buffer; + int img_buffer_size = 0; + unsigned char *img_buffer = temp_img_buffer; - // Calculate how long it takes to actually send the frame - struct timeval frameStartTime; - gettimeofday( &frameStartTime, NULL ); - - fprintf( stdout, "--ZoneMinderFrame\r\n" ); - switch( type ) - { - case STREAM_JPEG : - send_image->EncodeJpeg( img_buffer, &img_buffer_size ); - fprintf( stdout, "Content-Type: image/jpeg\r\n" ); - break; - case STREAM_RAW : - fprintf( stdout, "Content-Type: image/x-rgb\r\n" ); - img_buffer = (uint8_t*)send_image->Buffer(); - img_buffer_size = send_image->Size(); - break; - case STREAM_ZIP : - fprintf( stdout, "Content-Type: image/x-rgbz\r\n" ); - unsigned long zip_buffer_size; - send_image->Zip( img_buffer, &zip_buffer_size ); - img_buffer_size = zip_buffer_size; - break; - default : - Fatal( "Unexpected frame type %d", type ); - break; - } - fprintf( stdout, "Content-Length: %d\r\n\r\n", img_buffer_size ); - if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) - { - if ( !zm_terminate ) - Error( "Unable to send stream frame: %s", strerror(errno) ); - return( false ); - } - fprintf( stdout, "\r\n\r\n" ); - fflush( stdout ); + // Calculate how long it takes to actually send the frame + struct timeval frameStartTime; + gettimeofday( &frameStartTime, NULL ); + + fprintf( stdout, "--ZoneMinderFrame\r\n" ); + switch( type ) + { + case STREAM_JPEG : + send_image->EncodeJpeg( img_buffer, &img_buffer_size ); + fprintf( stdout, "Content-Type: image/jpeg\r\n" ); + break; + case STREAM_RAW : + fprintf( stdout, "Content-Type: image/x-rgb\r\n" ); + img_buffer = (uint8_t*)send_image->Buffer(); + img_buffer_size = send_image->Size(); + break; + case STREAM_ZIP : + fprintf( stdout, "Content-Type: image/x-rgbz\r\n" ); + unsigned long zip_buffer_size; + send_image->Zip( img_buffer, &zip_buffer_size ); + img_buffer_size = zip_buffer_size; + break; + default : + Fatal( "Unexpected frame type %d", type ); + break; + } + fprintf( stdout, "Content-Length: %d\r\n\r\n", img_buffer_size ); + if ( fwrite( img_buffer, img_buffer_size, 1, stdout ) != 1 ) + { + if ( !zm_terminate ) + Error( "Unable to send stream frame: %s", strerror(errno) ); + return( false ); + } + fprintf( stdout, "\r\n\r\n" ); + fflush( stdout ); - struct timeval frameEndTime; - gettimeofday( &frameEndTime, NULL ); + struct timeval frameEndTime; + gettimeofday( &frameEndTime, NULL ); - int frameSendTime = tvDiffMsec( frameStartTime, frameEndTime ); - if ( frameSendTime > 1000/maxfps ) - { - maxfps /= 1.5; - Error( "Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps ); - } - } - last_frame_sent = TV_2_FLOAT( now ); - return( true ); + int frameSendTime = tvDiffMsec( frameStartTime, frameEndTime ); + if ( frameSendTime > 1000/maxfps ) + { + maxfps /= 1.5; + Error( "Frame send time %d msec too slow, throttling maxfps to %.2f", frameSendTime, maxfps ); + } + } + last_frame_sent = TV_2_FLOAT( now ); + return( true ); } void MonitorStream::runStream() { - if ( type == STREAM_SINGLE ) - { - // Not yet migrated over to stream class - monitor->SingleImage( scale ); - return; - } + if ( type == STREAM_SINGLE ) + { + // Not yet migrated over to stream class + monitor->SingleImage( scale ); + return; + } - openComms(); + openComms(); - checkInitialised(); + checkInitialised(); - updateFrameRate( monitor->GetFPS() ); + updateFrameRate( monitor->GetFPS() ); - if ( type == STREAM_JPEG ) - fprintf( stdout, "Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame\r\n\r\n" ); + if ( type == STREAM_JPEG ) + fprintf( stdout, "Content-Type: multipart/x-mixed-replace;boundary=ZoneMinderFrame\r\n\r\n" ); - int last_read_index = monitor->image_buffer_count; + int last_read_index = monitor->image_buffer_count; - time_t stream_start_time; - time( &stream_start_time ); + time_t stream_start_time; + time( &stream_start_time ); - frame_count = 0; + frame_count = 0; - temp_image_buffer = 0; - temp_image_buffer_count = playback_buffer; - temp_read_index = temp_image_buffer_count; - temp_write_index = temp_image_buffer_count; + temp_image_buffer = 0; + temp_image_buffer_count = playback_buffer; + temp_read_index = temp_image_buffer_count; + temp_write_index = temp_image_buffer_count; - char *swap_path = 0; - bool buffered_playback = false; + char *swap_path = 0; + bool buffered_playback = false; - // 15 is the max length for the swap path suffix, /zmswap-whatever, assuming max 6 digits for monitor id - const int max_swap_len_suffix = 15; + // 15 is the max length for the swap path suffix, /zmswap-whatever, assuming max 6 digits for monitor id + const int max_swap_len_suffix = 15; - int swap_path_length = strlen(config.path_swap)+1; // +1 for NULL terminator + int swap_path_length = strlen(config.path_swap)+1; // +1 for NULL terminator - if ( connkey && playback_buffer > 0 ) { + if ( connkey && playback_buffer > 0 ) { - if ( swap_path_length + max_swap_len_suffix > PATH_MAX ) { - Error( "Swap Path is too long. %d > %d ", swap_path_length+max_swap_len_suffix, PATH_MAX ); - } else { - swap_path = (char *)malloc( swap_path_length+max_swap_len_suffix ); - Debug( 3, "Checking swap image path %s", config.path_swap ); - strncpy( swap_path, config.path_swap, swap_path_length ); - if ( checkSwapPath( swap_path, false ) ) { - snprintf( &(swap_path[swap_path_length]), max_swap_len_suffix, "/zmswap-m%d", monitor->Id() ); - if ( checkSwapPath( swap_path, true ) ) { - snprintf( &(swap_path[swap_path_length]), max_swap_len_suffix, "/zmswap-q%06d", connkey ); - if ( checkSwapPath( swap_path, true ) ) { - buffered_playback = true; - } - } - } + if ( swap_path_length + max_swap_len_suffix > PATH_MAX ) { + Error( "Swap Path is too long. %d > %d ", swap_path_length+max_swap_len_suffix, PATH_MAX ); + } else { + swap_path = (char *)malloc( swap_path_length+max_swap_len_suffix ); + Debug( 3, "Checking swap image path %s", config.path_swap ); + strncpy( swap_path, config.path_swap, swap_path_length ); + if ( checkSwapPath( swap_path, false ) ) { + snprintf( &(swap_path[swap_path_length]), max_swap_len_suffix, "/zmswap-m%d", monitor->Id() ); + if ( checkSwapPath( swap_path, true ) ) { + snprintf( &(swap_path[swap_path_length]), max_swap_len_suffix, "/zmswap-q%06d", connkey ); + if ( checkSwapPath( swap_path, true ) ) { + buffered_playback = true; + } + } + } - if ( !buffered_playback ) { - Error( "Unable to validate swap image path, disabling buffered playback" ); - } else { - Debug( 2, "Assigning temporary buffer" ); - temp_image_buffer = new SwapImage[temp_image_buffer_count]; - memset( temp_image_buffer, 0, sizeof(*temp_image_buffer)*temp_image_buffer_count ); - Debug( 2, "Assigned temporary buffer" ); - } - } - } + if ( !buffered_playback ) { + Error( "Unable to validate swap image path, disabling buffered playback" ); + } else { + Debug( 2, "Assigning temporary buffer" ); + temp_image_buffer = new SwapImage[temp_image_buffer_count]; + memset( temp_image_buffer, 0, sizeof(*temp_image_buffer)*temp_image_buffer_count ); + Debug( 2, "Assigned temporary buffer" ); + } + } + } - float max_secs_since_last_sent_frame = 10.0; //should be > keep alive amount (5 secs) - while ( !zm_terminate ) - { - bool got_command = false; - if ( feof( stdout ) || ferror( stdout ) || !monitor->ShmValid() ) - { - break; - } + float max_secs_since_last_sent_frame = 10.0; //should be > keep alive amount (5 secs) + while ( !zm_terminate ) + { + bool got_command = false; + if ( feof( stdout ) || ferror( stdout ) || !monitor->ShmValid() ) + { + break; + } - gettimeofday( &now, NULL ); + gettimeofday( &now, NULL ); - if ( connkey ) - { - while(checkCommandQueue()) { - got_command = true; - } - } + if ( connkey ) + { + while(checkCommandQueue()) { + got_command = true; + } + } - //bool frame_sent = false; - if ( buffered_playback && delayed ) - { - if ( temp_read_index == temp_write_index ) - { - // Go back to live viewing - Debug( 1, "Exceeded temporary streaming buffer" ); - // Clear paused flag - paused = false; - // Clear delayed_play flag - delayed = false; - replay_rate = ZM_RATE_BASE; - } - else - { - if ( !paused ) - { - int temp_index = MOD_ADD( temp_read_index, 0, temp_image_buffer_count ); - //Debug( 3, "tri: %d, ti: %d", temp_read_index, temp_index ); - SwapImage *swap_image = &temp_image_buffer[temp_index]; + //bool frame_sent = false; + if ( buffered_playback && delayed ) + { + if ( temp_read_index == temp_write_index ) + { + // Go back to live viewing + Debug( 1, "Exceeded temporary streaming buffer" ); + // Clear paused flag + paused = false; + // Clear delayed_play flag + delayed = false; + replay_rate = ZM_RATE_BASE; + } + else + { + if ( !paused ) + { + int temp_index = MOD_ADD( temp_read_index, 0, temp_image_buffer_count ); + //Debug( 3, "tri: %d, ti: %d", temp_read_index, temp_index ); + SwapImage *swap_image = &temp_image_buffer[temp_index]; - if ( !swap_image->valid ) - { - paused = true; - delayed = true; - temp_read_index = MOD_ADD( temp_read_index, (replay_rate>=0?-1:1), temp_image_buffer_count ); - } - else - { - //Debug( 3, "siT: %f, lfT: %f", TV_2_FLOAT( swap_image->timestamp ), TV_2_FLOAT( last_frame_timestamp ) ); - double expected_delta_time = ((TV_2_FLOAT( swap_image->timestamp ) - TV_2_FLOAT( last_frame_timestamp )) * ZM_RATE_BASE)/replay_rate; - double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent; + if ( !swap_image->valid ) + { + paused = true; + delayed = true; + temp_read_index = MOD_ADD( temp_read_index, (replay_rate>=0?-1:1), temp_image_buffer_count ); + } + else + { + //Debug( 3, "siT: %f, lfT: %f", TV_2_FLOAT( swap_image->timestamp ), TV_2_FLOAT( last_frame_timestamp ) ); + double expected_delta_time = ((TV_2_FLOAT( swap_image->timestamp ) - TV_2_FLOAT( last_frame_timestamp )) * ZM_RATE_BASE)/replay_rate; + double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent; - //Debug( 3, "eDT: %.3lf, aDT: %.3f, lFS:%.3f, NOW:%.3f", expected_delta_time, actual_delta_time, last_frame_sent, TV_2_FLOAT( now ) ); - // If the next frame is due - if ( actual_delta_time > expected_delta_time ) - { - //Debug( 2, "eDT: %.3lf, aDT: %.3f", expected_delta_time, actual_delta_time ); - if ( temp_index%frame_mod == 0 ) - { - Debug( 2, "Sending delayed frame %d", temp_index ); - // Send the next frame - if ( !sendFrame( temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp ) ) - zm_terminate = true; - memcpy( &last_frame_timestamp, &(swap_image->timestamp), sizeof(last_frame_timestamp) ); - //frame_sent = true; - } - temp_read_index = MOD_ADD( temp_read_index, (replay_rate>0?1:-1), temp_image_buffer_count ); - } - } - } - else if ( step != 0 ) - { - temp_read_index = MOD_ADD( temp_read_index, (step>0?1:-1), temp_image_buffer_count ); + //Debug( 3, "eDT: %.3lf, aDT: %.3f, lFS:%.3f, NOW:%.3f", expected_delta_time, actual_delta_time, last_frame_sent, TV_2_FLOAT( now ) ); + // If the next frame is due + if ( actual_delta_time > expected_delta_time ) + { + //Debug( 2, "eDT: %.3lf, aDT: %.3f", expected_delta_time, actual_delta_time ); + if ( temp_index%frame_mod == 0 ) + { + Debug( 2, "Sending delayed frame %d", temp_index ); + // Send the next frame + if ( !sendFrame( temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp ) ) + zm_terminate = true; + memcpy( &last_frame_timestamp, &(swap_image->timestamp), sizeof(last_frame_timestamp) ); + //frame_sent = true; + } + temp_read_index = MOD_ADD( temp_read_index, (replay_rate>0?1:-1), temp_image_buffer_count ); + } + } + } + else if ( step != 0 ) + { + temp_read_index = MOD_ADD( temp_read_index, (step>0?1:-1), temp_image_buffer_count ); - SwapImage *swap_image = &temp_image_buffer[temp_read_index]; + SwapImage *swap_image = &temp_image_buffer[temp_read_index]; - // Send the next frame - if ( !sendFrame( temp_image_buffer[temp_read_index].file_name, &temp_image_buffer[temp_read_index].timestamp ) ) - zm_terminate = true; - memcpy( &last_frame_timestamp, &(swap_image->timestamp), sizeof(last_frame_timestamp) ); - //frame_sent = true; - step = 0; - } - else - { - int temp_index = MOD_ADD( temp_read_index, 0, temp_image_buffer_count ); + // Send the next frame + if ( !sendFrame( temp_image_buffer[temp_read_index].file_name, &temp_image_buffer[temp_read_index].timestamp ) ) + zm_terminate = true; + memcpy( &last_frame_timestamp, &(swap_image->timestamp), sizeof(last_frame_timestamp) ); + //frame_sent = true; + step = 0; + } + else + { + int temp_index = MOD_ADD( temp_read_index, 0, temp_image_buffer_count ); - double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent; - if ( got_command || actual_delta_time > 5 ) - { - // Send keepalive - Debug( 2, "Sending keepalive frame %d", temp_index ); - // Send the next frame - if ( !sendFrame( temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp ) ) - zm_terminate = true; - //frame_sent = true; - } - } - } - if ( temp_read_index == temp_write_index ) - { - // Go back to live viewing - Warning( "Rewound over write index, resuming live play" ); - // Clear paused flag - paused = false; - // Clear delayed_play flag - delayed = false; - replay_rate = ZM_RATE_BASE; - } - } - if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index ) - { - int index = monitor->shared_data->last_write_index%monitor->image_buffer_count; - last_read_index = monitor->shared_data->last_write_index; - //Debug( 1, "%d: %x - %x", index, image_buffer[index].image, image_buffer[index].image->buffer ); - if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) - { - if ( !paused && !delayed ) - { - // Send the next frame - Monitor::Snapshot *snap = &monitor->image_buffer[index]; + double actual_delta_time = TV_2_FLOAT( now ) - last_frame_sent; + if ( got_command || actual_delta_time > 5 ) + { + // Send keepalive + Debug( 2, "Sending keepalive frame %d", temp_index ); + // Send the next frame + if ( !sendFrame( temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp ) ) + zm_terminate = true; + //frame_sent = true; + } + } + } + if ( temp_read_index == temp_write_index ) + { + // Go back to live viewing + Warning( "Rewound over write index, resuming live play" ); + // Clear paused flag + paused = false; + // Clear delayed_play flag + delayed = false; + replay_rate = ZM_RATE_BASE; + } + } + if ( (unsigned int)last_read_index != monitor->shared_data->last_write_index ) + { + int index = monitor->shared_data->last_write_index%monitor->image_buffer_count; + last_read_index = monitor->shared_data->last_write_index; + //Debug( 1, "%d: %x - %x", index, image_buffer[index].image, image_buffer[index].image->buffer ); + if ( (frame_mod == 1) || ((frame_count%frame_mod) == 0) ) + { + if ( !paused && !delayed ) + { + // Send the next frame + Monitor::Snapshot *snap = &monitor->image_buffer[index]; - if ( !sendFrame( snap->image, snap->timestamp ) ) - zm_terminate = true; - memcpy( &last_frame_timestamp, snap->timestamp, sizeof(last_frame_timestamp) ); - //frame_sent = true; + if ( !sendFrame( snap->image, snap->timestamp ) ) + zm_terminate = true; + memcpy( &last_frame_timestamp, snap->timestamp, sizeof(last_frame_timestamp) ); + //frame_sent = true; - temp_read_index = temp_write_index; - } - } - if ( buffered_playback ) - { - if ( monitor->shared_data->valid ) - { - if ( monitor->image_buffer[index].timestamp->tv_sec ) - { - int temp_index = temp_write_index%temp_image_buffer_count; - Debug( 2, "Storing frame %d", temp_index ); - if ( !temp_image_buffer[temp_index].valid ) - { - snprintf( temp_image_buffer[temp_index].file_name, sizeof(temp_image_buffer[0].file_name), "%s/zmswap-i%05d.jpg", swap_path, temp_index ); - temp_image_buffer[temp_index].valid = true; - } - memcpy( &(temp_image_buffer[temp_index].timestamp), monitor->image_buffer[index].timestamp, sizeof(temp_image_buffer[0].timestamp) ); - monitor->image_buffer[index].image->WriteJpeg( temp_image_buffer[temp_index].file_name, config.jpeg_file_quality ); - temp_write_index = MOD_ADD( temp_write_index, 1, temp_image_buffer_count ); - if ( temp_write_index == temp_read_index ) - { - // Go back to live viewing - Warning( "Exceeded temporary buffer, resuming live play" ); - // Clear paused flag - paused = false; - // Clear delayed_play flag - delayed = false; - replay_rate = ZM_RATE_BASE; - } - } - else - { - Warning( "Unable to store frame as timestamp invalid" ); - } - } - else - { - Warning( "Unable to store frame as shared memory invalid" ); - } - } - frame_count++; - } - usleep( (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2))) ); - if ( ttl ) - { - if ( (now.tv_sec - stream_start_time) > ttl ) - { - break; - } - } - if ( (TV_2_FLOAT( now ) - last_frame_sent) > max_secs_since_last_sent_frame ) - { - Error( "Terminating, last frame sent time %f secs more than maximum of %f", TV_2_FLOAT( now ) - last_frame_sent, max_secs_since_last_sent_frame ); - break; - } - } - if ( buffered_playback ) - { - char swap_path[PATH_MAX] = ""; + temp_read_index = temp_write_index; + } + } + if ( buffered_playback ) + { + if ( monitor->shared_data->valid ) + { + if ( monitor->image_buffer[index].timestamp->tv_sec ) + { + int temp_index = temp_write_index%temp_image_buffer_count; + Debug( 2, "Storing frame %d", temp_index ); + if ( !temp_image_buffer[temp_index].valid ) + { + snprintf( temp_image_buffer[temp_index].file_name, sizeof(temp_image_buffer[0].file_name), "%s/zmswap-i%05d.jpg", swap_path, temp_index ); + temp_image_buffer[temp_index].valid = true; + } + memcpy( &(temp_image_buffer[temp_index].timestamp), monitor->image_buffer[index].timestamp, sizeof(temp_image_buffer[0].timestamp) ); + monitor->image_buffer[index].image->WriteJpeg( temp_image_buffer[temp_index].file_name, config.jpeg_file_quality ); + temp_write_index = MOD_ADD( temp_write_index, 1, temp_image_buffer_count ); + if ( temp_write_index == temp_read_index ) + { + // Go back to live viewing + Warning( "Exceeded temporary buffer, resuming live play" ); + // Clear paused flag + paused = false; + // Clear delayed_play flag + delayed = false; + replay_rate = ZM_RATE_BASE; + } + } + else + { + Warning( "Unable to store frame as timestamp invalid" ); + } + } + else + { + Warning( "Unable to store frame as shared memory invalid" ); + } + } + frame_count++; + } + usleep( (unsigned long)((1000000 * ZM_RATE_BASE)/((base_fps?base_fps:1)*abs(replay_rate*2))) ); + if ( ttl ) + { + if ( (now.tv_sec - stream_start_time) > ttl ) + { + break; + } + } + if ( (TV_2_FLOAT( now ) - last_frame_sent) > max_secs_since_last_sent_frame ) + { + Error( "Terminating, last frame sent time %f secs more than maximum of %f", TV_2_FLOAT( now ) - last_frame_sent, max_secs_since_last_sent_frame ); + break; + } + } + if ( buffered_playback ) + { + char swap_path[PATH_MAX] = ""; - snprintf( swap_path, sizeof(swap_path), "%s/zmswap-m%d/zmswap-q%06d", config.path_swap, monitor->Id(), connkey ); - Debug( 1, "Cleaning swap files from %s", swap_path ); - struct stat stat_buf; - if ( stat( swap_path, &stat_buf ) < 0 ) - { - if ( errno != ENOENT ) - { - Error( "Can't stat '%s': %s", swap_path, strerror(errno) ); - } - } - else if ( !S_ISDIR(stat_buf.st_mode) ) - { - Error( "Swap image path '%s' is not a directory", swap_path ); - } - else - { - char glob_pattern[PATH_MAX] = ""; + snprintf( swap_path, sizeof(swap_path), "%s/zmswap-m%d/zmswap-q%06d", config.path_swap, monitor->Id(), connkey ); + Debug( 1, "Cleaning swap files from %s", swap_path ); + struct stat stat_buf; + if ( stat( swap_path, &stat_buf ) < 0 ) + { + if ( errno != ENOENT ) + { + Error( "Can't stat '%s': %s", swap_path, strerror(errno) ); + } + } + else if ( !S_ISDIR(stat_buf.st_mode) ) + { + Error( "Swap image path '%s' is not a directory", swap_path ); + } + else + { + char glob_pattern[PATH_MAX] = ""; - snprintf( glob_pattern, sizeof(glob_pattern), "%s/*.*", swap_path ); - glob_t pglob; - int glob_status = glob( glob_pattern, 0, 0, &pglob ); - if ( glob_status != 0 ) - { - if ( glob_status < 0 ) - { - Error( "Can't glob '%s': %s", glob_pattern, strerror(errno) ); - } - else - { - Debug( 1, "Can't glob '%s': %d", glob_pattern, glob_status ); - } - } - else - { - for ( unsigned int i = 0; i < pglob.gl_pathc; i++ ) - { - if ( unlink( pglob.gl_pathv[i] ) < 0 ) - { - Error( "Can't unlink '%s': %s", pglob.gl_pathv[i], strerror(errno) ); - } - } - } - globfree( &pglob ); - if ( rmdir( swap_path ) < 0 ) - { - Error( "Can't rmdir '%s': %s", swap_path, strerror(errno) ); - } - } - } - if ( swap_path ) free( swap_path ); - closeComms(); + snprintf( glob_pattern, sizeof(glob_pattern), "%s/*.*", swap_path ); + glob_t pglob; + int glob_status = glob( glob_pattern, 0, 0, &pglob ); + if ( glob_status != 0 ) + { + if ( glob_status < 0 ) + { + Error( "Can't glob '%s': %s", glob_pattern, strerror(errno) ); + } + else + { + Debug( 1, "Can't glob '%s': %d", glob_pattern, glob_status ); + } + } + else + { + for ( unsigned int i = 0; i < pglob.gl_pathc; i++ ) + { + if ( unlink( pglob.gl_pathv[i] ) < 0 ) + { + Error( "Can't unlink '%s': %s", pglob.gl_pathv[i], strerror(errno) ); + } + } + } + globfree( &pglob ); + if ( rmdir( swap_path ) < 0 ) + { + Error( "Can't rmdir '%s': %s", swap_path, strerror(errno) ); + } + } + } + if ( swap_path ) free( swap_path ); + closeComms(); } void Monitor::SingleImage( int scale) { - int img_buffer_size = 0; - static JOCTET img_buffer[ZM_MAX_IMAGE_SIZE]; - Image scaled_image; - int index = shared_data->last_write_index%image_buffer_count; - Snapshot *snap = &image_buffer[index]; - Image *snap_image = snap->image; + int img_buffer_size = 0; + static JOCTET img_buffer[ZM_MAX_IMAGE_SIZE]; + Image scaled_image; + int index = shared_data->last_write_index%image_buffer_count; + Snapshot *snap = &image_buffer[index]; + Image *snap_image = snap->image; - if ( scale != ZM_SCALE_BASE ) - { - scaled_image.Assign( *snap_image ); - scaled_image.Scale( scale ); - snap_image = &scaled_image; - } - if ( !config.timestamp_on_capture ) - { - TimestampImage( snap_image, snap->timestamp ); - } - snap_image->EncodeJpeg( img_buffer, &img_buffer_size ); - - fprintf( stdout, "Content-Length: %d\r\n", img_buffer_size ); - fprintf( stdout, "Content-Type: image/jpeg\r\n\r\n" ); - fwrite( img_buffer, img_buffer_size, 1, stdout ); + if ( scale != ZM_SCALE_BASE ) + { + scaled_image.Assign( *snap_image ); + scaled_image.Scale( scale ); + snap_image = &scaled_image; + } + if ( !config.timestamp_on_capture ) + { + TimestampImage( snap_image, snap->timestamp ); + } + snap_image->EncodeJpeg( img_buffer, &img_buffer_size ); + + fprintf( stdout, "Content-Length: %d\r\n", img_buffer_size ); + fprintf( stdout, "Content-Type: image/jpeg\r\n\r\n" ); + fwrite( img_buffer, img_buffer_size, 1, stdout ); } void Monitor::SingleImageRaw( int scale) { - Image scaled_image; - int index = shared_data->last_write_index%image_buffer_count; - Snapshot *snap = &image_buffer[index]; - Image *snap_image = snap->image; + Image scaled_image; + int index = shared_data->last_write_index%image_buffer_count; + Snapshot *snap = &image_buffer[index]; + Image *snap_image = snap->image; - if ( scale != ZM_SCALE_BASE ) - { - scaled_image.Assign( *snap_image ); - scaled_image.Scale( scale ); - snap_image = &scaled_image; - } - if ( !config.timestamp_on_capture ) - { - TimestampImage( snap_image, snap->timestamp ); - } - - fprintf( stdout, "Content-Length: %d\r\n", snap_image->Size() ); - fprintf( stdout, "Content-Type: image/x-rgb\r\n\r\n" ); - fwrite( snap_image->Buffer(), snap_image->Size(), 1, stdout ); + if ( scale != ZM_SCALE_BASE ) + { + scaled_image.Assign( *snap_image ); + scaled_image.Scale( scale ); + snap_image = &scaled_image; + } + if ( !config.timestamp_on_capture ) + { + TimestampImage( snap_image, snap->timestamp ); + } + + fprintf( stdout, "Content-Length: %d\r\n", snap_image->Size() ); + fprintf( stdout, "Content-Type: image/x-rgb\r\n\r\n" ); + fwrite( snap_image->Buffer(), snap_image->Size(), 1, stdout ); } void Monitor::SingleImageZip( int scale) { - unsigned long img_buffer_size = 0; - static Bytef img_buffer[ZM_MAX_IMAGE_SIZE]; - Image scaled_image; - int index = shared_data->last_write_index%image_buffer_count; - Snapshot *snap = &image_buffer[index]; - Image *snap_image = snap->image; + unsigned long img_buffer_size = 0; + static Bytef img_buffer[ZM_MAX_IMAGE_SIZE]; + Image scaled_image; + int index = shared_data->last_write_index%image_buffer_count; + Snapshot *snap = &image_buffer[index]; + Image *snap_image = snap->image; - if ( scale != ZM_SCALE_BASE ) - { - scaled_image.Assign( *snap_image ); - scaled_image.Scale( scale ); - snap_image = &scaled_image; - } - if ( !config.timestamp_on_capture ) - { - TimestampImage( snap_image, snap->timestamp ); - } - snap_image->Zip( img_buffer, &img_buffer_size ); - - fprintf( stdout, "Content-Length: %ld\r\n", img_buffer_size ); - fprintf( stdout, "Content-Type: image/x-rgbz\r\n\r\n" ); - fwrite( img_buffer, img_buffer_size, 1, stdout ); + if ( scale != ZM_SCALE_BASE ) + { + scaled_image.Assign( *snap_image ); + scaled_image.Scale( scale ); + snap_image = &scaled_image; + } + if ( !config.timestamp_on_capture ) + { + TimestampImage( snap_image, snap->timestamp ); + } + snap_image->Zip( img_buffer, &img_buffer_size ); + + fprintf( stdout, "Content-Length: %ld\r\n", img_buffer_size ); + fprintf( stdout, "Content-Type: image/x-rgbz\r\n\r\n" ); + fwrite( img_buffer, img_buffer_size, 1, stdout ); } diff --git a/src/zm_monitor.h b/src/zm_monitor.h index e00490d7f..a4d4b4378 100644 --- a/src/zm_monitor.h +++ b/src/zm_monitor.h @@ -48,505 +48,505 @@ // class Monitor { -friend class MonitorStream; + friend class MonitorStream; -public: - typedef enum - { - QUERY=0, - CAPTURE, - ANALYSIS - } Purpose; + public: + typedef enum + { + QUERY=0, + CAPTURE, + ANALYSIS + } Purpose; - typedef enum - { - NONE=1, - MONITOR, - MODECT, - RECORD, - MOCORD, - NODECT - } Function; + typedef enum + { + NONE=1, + MONITOR, + MODECT, + RECORD, + MOCORD, + NODECT + } Function; - typedef enum - { - ROTATE_0=1, - ROTATE_90, - ROTATE_180, - ROTATE_270, - FLIP_HORI, - FLIP_VERT - } Orientation; + typedef enum + { + ROTATE_0=1, + ROTATE_90, + ROTATE_180, + ROTATE_270, + FLIP_HORI, + FLIP_VERT + } Orientation; - typedef enum - { - IDLE, - PREALARM, - ALARM, - ALERT, - TAPE - } State; + typedef enum + { + IDLE, + PREALARM, + ALARM, + ALERT, + TAPE + } State; -protected: - typedef std::set ZoneSet; + protected: + typedef std::set ZoneSet; - typedef enum { GET_SETTINGS=0x1, SET_SETTINGS=0x2, RELOAD=0x4, SUSPEND=0x10, RESUME=0x20 } Action; + typedef enum { GET_SETTINGS=0x1, SET_SETTINGS=0x2, RELOAD=0x4, SUSPEND=0x10, RESUME=0x20 } Action; - typedef enum { CLOSE_TIME, CLOSE_IDLE, CLOSE_ALARM } EventCloseMode; + typedef enum { CLOSE_TIME, CLOSE_IDLE, CLOSE_ALARM } EventCloseMode; - /* sizeof(SharedData) expected to be 336 bytes on 32bit and 64bit */ - typedef struct - { - uint32_t size; /* +0 */ - uint32_t last_write_index; /* +4 */ - uint32_t last_read_index; /* +8 */ - uint32_t state; /* +12 */ - uint32_t last_event; /* +16 */ - uint32_t action; /* +20 */ - int32_t brightness; /* +24 */ - int32_t hue; /* +28 */ - int32_t colour; /* +32 */ - int32_t contrast; /* +36 */ - int32_t alarm_x; /* +40 */ - int32_t alarm_y; /* +44 */ - uint8_t valid; /* +48 */ - uint8_t active; /* +49 */ - uint8_t signal; /* +50 */ - uint8_t format; /* +51 */ - uint32_t imagesize; /* +52 */ - uint32_t epadding1; /* +56 */ - uint32_t epadding2; /* +60 */ - /* - ** This keeps 32bit time_t and 64bit time_t identical and compatible as long as time is before 2038. - ** Shared memory layout should be identical for both 32bit and 64bit and is multiples of 16. - */ - union { /* +64 */ - time_t last_write_time; - uint64_t extrapad1; - }; - union { /* +72 */ - time_t last_read_time; - uint64_t extrapad2; - }; - uint8_t control_state[256]; /* +80 */ - - } SharedData; + /* sizeof(SharedData) expected to be 336 bytes on 32bit and 64bit */ + typedef struct + { + uint32_t size; /* +0 */ + uint32_t last_write_index; /* +4 */ + uint32_t last_read_index; /* +8 */ + uint32_t state; /* +12 */ + uint32_t last_event; /* +16 */ + uint32_t action; /* +20 */ + int32_t brightness; /* +24 */ + int32_t hue; /* +28 */ + int32_t colour; /* +32 */ + int32_t contrast; /* +36 */ + int32_t alarm_x; /* +40 */ + int32_t alarm_y; /* +44 */ + uint8_t valid; /* +48 */ + uint8_t active; /* +49 */ + uint8_t signal; /* +50 */ + uint8_t format; /* +51 */ + uint32_t imagesize; /* +52 */ + uint32_t epadding1; /* +56 */ + uint32_t epadding2; /* +60 */ + /* + ** This keeps 32bit time_t and 64bit time_t identical and compatible as long as time is before 2038. + ** Shared memory layout should be identical for both 32bit and 64bit and is multiples of 16. + */ + union { /* +64 */ + time_t last_write_time; + uint64_t extrapad1; + }; + union { /* +72 */ + time_t last_read_time; + uint64_t extrapad2; + }; + uint8_t control_state[256]; /* +80 */ - typedef enum { TRIGGER_CANCEL, TRIGGER_ON, TRIGGER_OFF } TriggerState; - - /* sizeof(TriggerData) expected to be 560 on 32bit & and 64bit */ - typedef struct - { - uint32_t size; - uint32_t trigger_state; - uint32_t trigger_score; - uint32_t padding; - char trigger_cause[32]; - char trigger_text[256]; - char trigger_showtext[256]; - } TriggerData; + } SharedData; - /* sizeof(Snapshot) expected to be 16 bytes on 32bit and 32 bytes on 64bit */ - struct Snapshot - { - struct timeval *timestamp; - Image *image; - void* padding; - }; + typedef enum { TRIGGER_CANCEL, TRIGGER_ON, TRIGGER_OFF } TriggerState; - //TODO: Technically we can't exclude this struct when people don't have avformat as the Memory.pm module doesn't know about avformat + /* sizeof(TriggerData) expected to be 560 on 32bit & and 64bit */ + typedef struct + { + uint32_t size; + uint32_t trigger_state; + uint32_t trigger_score; + uint32_t padding; + char trigger_cause[32]; + char trigger_text[256]; + char trigger_showtext[256]; + } TriggerData; + + /* sizeof(Snapshot) expected to be 16 bytes on 32bit and 32 bytes on 64bit */ + struct Snapshot + { + struct timeval *timestamp; + Image *image; + void* padding; + }; + + //TODO: Technically we can't exclude this struct when people don't have avformat as the Memory.pm module doesn't know about avformat #if 1 - //sizeOf(VideoStoreData) expected to be 4104 bytes on 32bit and 64bit - typedef struct - { - uint32_t size; - char event_file[4096]; - uint32_t recording; //bool arch dependent so use uint32 instead - //uint32_t frameNumber; - } VideoStoreData; - + //sizeOf(VideoStoreData) expected to be 4104 bytes on 32bit and 64bit + typedef struct + { + uint32_t size; + char event_file[4096]; + uint32_t recording; //bool arch dependent so use uint32 instead + //uint32_t frameNumber; + } VideoStoreData; + #endif // HAVE_LIBAVFORMAT - class MonitorLink { - protected: - unsigned int id; - char name[64]; + class MonitorLink { + protected: + unsigned int id; + char name[64]; - bool connected; - time_t last_connect_time; + bool connected; + time_t last_connect_time; #if ZM_MEM_MAPPED - int map_fd; - char mem_file[PATH_MAX]; + int map_fd; + char mem_file[PATH_MAX]; #else // ZM_MEM_MAPPED - int shm_id; + int shm_id; #endif // ZM_MEM_MAPPED - off_t mem_size; - unsigned char *mem_ptr; + off_t mem_size; + unsigned char *mem_ptr; - volatile SharedData *shared_data; - volatile TriggerData *trigger_data; - volatile VideoStoreData *video_store_data; + volatile SharedData *shared_data; + volatile TriggerData *trigger_data; + volatile VideoStoreData *video_store_data; - int last_state; - int last_event; - + int last_state; + int last_event; - public: - MonitorLink( int p_id, const char *p_name ); - ~MonitorLink(); - inline int Id() const { - return( id ); - } - inline const char *Name() const { - return( name ); - } + public: + MonitorLink( int p_id, const char *p_name ); + ~MonitorLink(); - inline bool isConnected() const { - return( connected ); - } - inline time_t getLastConnectTime() const { - return( last_connect_time ); - } + inline int Id() const { + return( id ); + } + inline const char *Name() const { + return( name ); + } - bool connect(); - bool disconnect(); + inline bool isConnected() const { + return( connected ); + } + inline time_t getLastConnectTime() const { + return( last_connect_time ); + } - bool isAlarmed(); - bool inAlarm(); - bool hasAlarmed(); - }; + bool connect(); + bool disconnect(); -protected: - // These are read from the DB and thereafter remain unchanged - unsigned int id; - char name[64]; - unsigned int server_id; // Id of the Server object - unsigned int storage_id; // Id of the Storage Object, which currently will just provide a path, but in future may do more. - Function function; // What the monitor is doing - bool enabled; // Whether the monitor is enabled or asleep - unsigned int width; // Normally the same as the camera, but not if partly rotated - unsigned int height; // Normally the same as the camera, but not if partly rotated - bool v4l_multi_buffer; - unsigned int v4l_captures_per_frame; - Orientation orientation; // Whether the image has to be rotated at all - unsigned int deinterlacing; + bool isAlarmed(); + bool inAlarm(); + bool hasAlarmed(); + }; - int savejpegspref; - int videowriterpref; - std::string encoderparams; - std::vector encoderparamsvec; - bool record_audio; // Whether to store the audio that we receive + protected: + // These are read from the DB and thereafter remain unchanged + unsigned int id; + char name[64]; + unsigned int server_id; // Id of the Server object + unsigned int storage_id; // Id of the Storage Object, which currently will just provide a path, but in future may do more. + Function function; // What the monitor is doing + bool enabled; // Whether the monitor is enabled or asleep + unsigned int width; // Normally the same as the camera, but not if partly rotated + unsigned int height; // Normally the same as the camera, but not if partly rotated + bool v4l_multi_buffer; + unsigned int v4l_captures_per_frame; + Orientation orientation; // Whether the image has to be rotated at all + unsigned int deinterlacing; - int brightness; // The statically saved brightness of the camera - int contrast; // The statically saved contrast of the camera - int hue; // The statically saved hue of the camera - int colour; // The statically saved colour of the camera - char event_prefix[64]; // The prefix applied to event names as they are created - char label_format[64]; // The format of the timestamp on the images - Coord label_coord; // The coordinates of the timestamp on the images - int label_size; // Size of the timestamp on the images - int image_buffer_count; // Size of circular image buffer, at least twice the size of the pre_event_count - int pre_event_buffer_count; // Size of dedicated circular pre event buffer used when analysis is not performed at capturing framerate, - // value is pre_event_count + alarm_frame_count - 1 - int warmup_count; // How many images to process before looking for events - int pre_event_count; // How many images to hold and prepend to an alarm event - int post_event_count; // How many unalarmed images must occur before the alarm state is reset - int stream_replay_buffer; // How many frames to store to support DVR functions, IGNORED from this object, passed directly into zms now - int section_length; // How long events should last in continuous modes - bool adaptive_skip; // Whether to use the newer adaptive algorithm for this monitor - int frame_skip; // How many frames to skip in continuous modes - int motion_frame_skip; // How many frames to skip in motion detection - double analysis_fps; // Target framerate for video analysis - unsigned int analysis_update_delay; // How long we wait before updating analysis parameters - int capture_delay; // How long we wait between capture frames - int alarm_capture_delay; // How long we wait between capture frames when in alarm state - int alarm_frame_count; // How many alarm frames are required before an event is triggered - int fps_report_interval; // How many images should be captured/processed between reporting the current FPS - int ref_blend_perc; // Percentage of new image going into reference image. - int alarm_ref_blend_perc; // Percentage of new image going into reference image during alarm. - bool track_motion; // Whether this monitor tries to track detected motion - Rgb signal_check_colour; // The colour that the camera will emit when no video signal detected - bool embed_exif; // Whether to embed Exif data into each image frame or not + int savejpegspref; + int videowriterpref; + std::string encoderparams; + std::vector encoderparamsvec; + bool record_audio; // Whether to store the audio that we receive - double fps; - Image delta_image; - Image ref_image; - Image alarm_image; // Used in creating analysis images, will be initialized in Analysis - Image write_image; // Used when creating snapshot images + int brightness; // The statically saved brightness of the camera + int contrast; // The statically saved contrast of the camera + int hue; // The statically saved hue of the camera + int colour; // The statically saved colour of the camera + char event_prefix[64]; // The prefix applied to event names as they are created + char label_format[64]; // The format of the timestamp on the images + Coord label_coord; // The coordinates of the timestamp on the images + int label_size; // Size of the timestamp on the images + int image_buffer_count; // Size of circular image buffer, at least twice the size of the pre_event_count + int pre_event_buffer_count; // Size of dedicated circular pre event buffer used when analysis is not performed at capturing framerate, + // value is pre_event_count + alarm_frame_count - 1 + int warmup_count; // How many images to process before looking for events + int pre_event_count; // How many images to hold and prepend to an alarm event + int post_event_count; // How many unalarmed images must occur before the alarm state is reset + int stream_replay_buffer; // How many frames to store to support DVR functions, IGNORED from this object, passed directly into zms now + int section_length; // How long events should last in continuous modes + bool adaptive_skip; // Whether to use the newer adaptive algorithm for this monitor + int frame_skip; // How many frames to skip in continuous modes + int motion_frame_skip; // How many frames to skip in motion detection + double analysis_fps; // Target framerate for video analysis + unsigned int analysis_update_delay; // How long we wait before updating analysis parameters + int capture_delay; // How long we wait between capture frames + int alarm_capture_delay; // How long we wait between capture frames when in alarm state + int alarm_frame_count; // How many alarm frames are required before an event is triggered + int fps_report_interval; // How many images should be captured/processed between reporting the current FPS + int ref_blend_perc; // Percentage of new image going into reference image. + int alarm_ref_blend_perc; // Percentage of new image going into reference image during alarm. + bool track_motion; // Whether this monitor tries to track detected motion + Rgb signal_check_colour; // The colour that the camera will emit when no video signal detected + bool embed_exif; // Whether to embed Exif data into each image frame or not - Purpose purpose; // What this monitor has been created to do - int event_count; - int image_count; - int ready_count; - int first_alarm_count; - int last_alarm_count; - int buffer_count; - int prealarm_count; - State state; - time_t start_time; - time_t last_fps_time; - time_t auto_resume_time; - unsigned int last_motion_score; + double fps; + Image delta_image; + Image ref_image; + Image alarm_image; // Used in creating analysis images, will be initialized in Analysis + Image write_image; // Used when creating snapshot images - EventCloseMode event_close_mode; + Purpose purpose; // What this monitor has been created to do + int event_count; + int image_count; + int ready_count; + int first_alarm_count; + int last_alarm_count; + int buffer_count; + int prealarm_count; + State state; + time_t start_time; + time_t last_fps_time; + time_t auto_resume_time; + unsigned int last_motion_score; + + EventCloseMode event_close_mode; #if ZM_MEM_MAPPED - int map_fd; - char mem_file[PATH_MAX]; + int map_fd; + char mem_file[PATH_MAX]; #else // ZM_MEM_MAPPED - int shm_id; + int shm_id; #endif // ZM_MEM_MAPPED - off_t mem_size; - unsigned char *mem_ptr; - Storage *storage; + off_t mem_size; + unsigned char *mem_ptr; + Storage *storage; - SharedData *shared_data; - TriggerData *trigger_data; - VideoStoreData *video_store_data; + SharedData *shared_data; + TriggerData *trigger_data; + VideoStoreData *video_store_data; - Snapshot *image_buffer; - Snapshot next_buffer; /* Used by four field deinterlacing */ - Snapshot *pre_event_buffer; + Snapshot *image_buffer; + Snapshot next_buffer; /* Used by four field deinterlacing */ + Snapshot *pre_event_buffer; - Camera *camera; + Camera *camera; - Event *event; + Event *event; - int n_zones; - Zone **zones; + int n_zones; + Zone **zones; - struct timeval **timestamps; - Image **images; + struct timeval **timestamps; + Image **images; - const unsigned char *privacy_bitmask; + const unsigned char *privacy_bitmask; - int n_linked_monitors; - MonitorLink **linked_monitors; + int n_linked_monitors; + MonitorLink **linked_monitors; -public: -// OurCheckAlarms seems to be unused. Check it on zm_monitor.cpp for more info. -//bool OurCheckAlarms( Zone *zone, const Image *pImage ); - Monitor( - int p_id, - const char *p_name, - unsigned int p_server_id, - unsigned int p_storage_id, - int p_function, - bool p_enabled, - const char *p_linked_monitors, - Camera *p_camera, - int p_orientation, - unsigned int p_deinterlacing, - int p_savejpegs, - int p_videowriter, - std::string p_encoderparams, - bool p_record_audio, - const char *p_event_prefix, - const char *p_label_format, - const Coord &p_label_coord, - int label_size, - int p_image_buffer_count, - int p_warmup_count, - int p_pre_event_count, - int p_post_event_count, - int p_stream_replay_buffer, - int p_alarm_frame_count, - int p_section_length, - int p_frame_skip, - int p_motion_frame_skip, - double p_analysis_fps, - unsigned int p_analysis_update_delay, - int p_capture_delay, - int p_alarm_capture_delay, - int p_fps_report_interval, - int p_ref_blend_perc, - int p_alarm_ref_blend_perc, - bool p_track_motion, - Rgb p_signal_check_colour, - bool p_embed_exif, - Purpose p_purpose, - int p_n_zones=0, - Zone *p_zones[]=0 - ); - ~Monitor(); + public: + // OurCheckAlarms seems to be unused. Check it on zm_monitor.cpp for more info. + //bool OurCheckAlarms( Zone *zone, const Image *pImage ); + Monitor( + int p_id, + const char *p_name, + unsigned int p_server_id, + unsigned int p_storage_id, + int p_function, + bool p_enabled, + const char *p_linked_monitors, + Camera *p_camera, + int p_orientation, + unsigned int p_deinterlacing, + int p_savejpegs, + int p_videowriter, + std::string p_encoderparams, + bool p_record_audio, + const char *p_event_prefix, + const char *p_label_format, + const Coord &p_label_coord, + int label_size, + int p_image_buffer_count, + int p_warmup_count, + int p_pre_event_count, + int p_post_event_count, + int p_stream_replay_buffer, + int p_alarm_frame_count, + int p_section_length, + int p_frame_skip, + int p_motion_frame_skip, + double p_analysis_fps, + unsigned int p_analysis_update_delay, + int p_capture_delay, + int p_alarm_capture_delay, + int p_fps_report_interval, + int p_ref_blend_perc, + int p_alarm_ref_blend_perc, + bool p_track_motion, + Rgb p_signal_check_colour, + bool p_embed_exif, + Purpose p_purpose, + int p_n_zones=0, + Zone *p_zones[]=0 + ); + ~Monitor(); - void AddZones( int p_n_zones, Zone *p_zones[] ); - void AddPrivacyBitmask( Zone *p_zones[] ); + void AddZones( int p_n_zones, Zone *p_zones[] ); + void AddPrivacyBitmask( Zone *p_zones[] ); - bool connect(); - inline int ShmValid() const { - return( shared_data->valid ); - } + bool connect(); + inline int ShmValid() const { + return( shared_data->valid ); + } - inline int Id() const { - return( id ); - } - inline const char *Name() const { - return( name ); - } - inline Storage *getStorage() { - if ( ! storage ) { - storage = new Storage( storage_id ); - } - return( storage ); - } - inline Function GetFunction() const { - return( function ); - } - inline bool Enabled() { - if ( function <= MONITOR ) - return( false ); - return( enabled ); - } - inline const char *EventPrefix() const { - return( event_prefix ); - } - inline bool Ready() { - if ( function <= MONITOR ) - return( false ); - return( image_count > ready_count ); - } - inline bool Active() { - if ( function <= MONITOR ) - return( false ); - return( enabled && shared_data->active ); - } - inline bool Exif() { - return( embed_exif ); - } + inline int Id() const { + return( id ); + } + inline const char *Name() const { + return( name ); + } + inline Storage *getStorage() { + if ( ! storage ) { + storage = new Storage( storage_id ); + } + return( storage ); + } + inline Function GetFunction() const { + return( function ); + } + inline bool Enabled() { + if ( function <= MONITOR ) + return( false ); + return( enabled ); + } + inline const char *EventPrefix() const { + return( event_prefix ); + } + inline bool Ready() { + if ( function <= MONITOR ) + return( false ); + return( image_count > ready_count ); + } + inline bool Active() { + if ( function <= MONITOR ) + return( false ); + return( enabled && shared_data->active ); + } + inline bool Exif() { + return( embed_exif ); + } - unsigned int Width() const { return( width ); } - unsigned int Height() const { return( height ); } - unsigned int Colours() const { return( camera->Colours() ); } - unsigned int SubpixelOrder() const { return( camera->SubpixelOrder() ); } + unsigned int Width() const { return width; } + unsigned int Height() const { return height; } + unsigned int Colours() const { return( camera->Colours() ); } + unsigned int SubpixelOrder() const { return( camera->SubpixelOrder() ); } - int GetOptSaveJPEGs() const { return( savejpegspref ); } - int GetOptVideoWriter() const { return( videowriterpref ); } - const std::vector* GetOptEncoderParams() const { return( &encoderparamsvec ); } - - State GetState() const; - int GetImage( int index=-1, int scale=100 ); - struct timeval GetTimestamp( int index=-1 ) const; - void UpdateAdaptiveSkip(); - useconds_t GetAnalysisRate(); - unsigned int GetAnalysisUpdateDelay() const { return( analysis_update_delay ); } - int GetCaptureDelay() const { return( capture_delay ); } - int GetAlarmCaptureDelay() const { return( alarm_capture_delay ); } - unsigned int GetLastReadIndex() const; - unsigned int GetLastWriteIndex() const; - unsigned int GetLastEvent() const; - double GetFPS() const; - void ForceAlarmOn( int force_score, const char *force_case, const char *force_text="" ); - void ForceAlarmOff(); - void CancelForced(); - TriggerState GetTriggerState() const { return( (TriggerState)(trigger_data?trigger_data->trigger_state:TRIGGER_CANCEL )); } + int GetOptSaveJPEGs() const { return( savejpegspref ); } + int GetOptVideoWriter() const { return( videowriterpref ); } + const std::vector* GetOptEncoderParams() const { return( &encoderparamsvec ); } - void actionReload(); - void actionEnable(); - void actionDisable(); - void actionSuspend(); - void actionResume(); + State GetState() const; + int GetImage( int index=-1, int scale=100 ); + struct timeval GetTimestamp( int index=-1 ) const; + void UpdateAdaptiveSkip(); + useconds_t GetAnalysisRate(); + unsigned int GetAnalysisUpdateDelay() const { return( analysis_update_delay ); } + int GetCaptureDelay() const { return( capture_delay ); } + int GetAlarmCaptureDelay() const { return( alarm_capture_delay ); } + unsigned int GetLastReadIndex() const; + unsigned int GetLastWriteIndex() const; + unsigned int GetLastEvent() const; + double GetFPS() const; + void ForceAlarmOn( int force_score, const char *force_case, const char *force_text="" ); + void ForceAlarmOff(); + void CancelForced(); + TriggerState GetTriggerState() const { return( (TriggerState)(trigger_data?trigger_data->trigger_state:TRIGGER_CANCEL )); } - int actionBrightness( int p_brightness=-1 ); - int actionHue( int p_hue=-1 ); - int actionColour( int p_colour=-1 ); - int actionContrast( int p_contrast=-1 ); + void actionReload(); + void actionEnable(); + void actionDisable(); + void actionSuspend(); + void actionResume(); - inline int PrimeCapture() { - return( camera->PrimeCapture() ); - } - inline int PreCapture() { - return( camera->PreCapture() ); - } - int Capture(); - int PostCapture() { - return( camera->PostCapture() ); - } + int actionBrightness( int p_brightness=-1 ); + int actionHue( int p_hue=-1 ); + int actionColour( int p_colour=-1 ); + int actionContrast( int p_contrast=-1 ); - unsigned int DetectMotion( const Image &comp_image, Event::StringSet &zoneSet ); - // DetectBlack seems to be unused. Check it on zm_monitor.cpp for more info. - //unsigned int DetectBlack( const Image &comp_image, Event::StringSet &zoneSet ); - bool CheckSignal( const Image *image ); - bool Analyse(); - void DumpImage( Image *dump_image ) const; - void TimestampImage( Image *ts_image, const struct timeval *ts_time ) const; - bool closeEvent(); + inline int PrimeCapture() { + return( camera->PrimeCapture() ); + } + inline int PreCapture() { + return( camera->PreCapture() ); + } + int Capture(); + int PostCapture() { + return( camera->PostCapture() ); + } - void Reload(); - void ReloadZones(); - void ReloadLinkedMonitors( const char * ); + unsigned int DetectMotion( const Image &comp_image, Event::StringSet &zoneSet ); + // DetectBlack seems to be unused. Check it on zm_monitor.cpp for more info. + //unsigned int DetectBlack( const Image &comp_image, Event::StringSet &zoneSet ); + bool CheckSignal( const Image *image ); + bool Analyse(); + void DumpImage( Image *dump_image ) const; + void TimestampImage( Image *ts_image, const struct timeval *ts_time ) const; + bool closeEvent(); - bool DumpSettings( char *output, bool verbose ); - void DumpZoneImage( const char *zone_string=0 ); + void Reload(); + void ReloadZones(); + void ReloadLinkedMonitors( const char * ); + + bool DumpSettings( char *output, bool verbose ); + void DumpZoneImage( const char *zone_string=0 ); #if ZM_HAS_V4L - static int LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ); + static int LoadLocalMonitors( const char *device, Monitor **&monitors, Purpose purpose ); #endif // ZM_HAS_V4L - static int LoadRemoteMonitors( const char *protocol, const char *host, const char*port, const char*path, Monitor **&monitors, Purpose purpose ); - static int LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ); + static int LoadRemoteMonitors( const char *protocol, const char *host, const char*port, const char*path, Monitor **&monitors, Purpose purpose ); + static int LoadFileMonitors( const char *file, Monitor **&monitors, Purpose purpose ); #if HAVE_LIBAVFORMAT - static int LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose purpose ); + static int LoadFfmpegMonitors( const char *file, Monitor **&monitors, Purpose purpose ); #endif // HAVE_LIBAVFORMAT - static Monitor *Load( unsigned int id, bool load_zones, Purpose purpose ); - //void writeStreamImage( Image *image, struct timeval *timestamp, int scale, int mag, int x, int y ); - //void StreamImages( int scale=100, int maxfps=10, time_t ttl=0, int msq_id=0 ); - //void StreamImagesRaw( int scale=100, int maxfps=10, time_t ttl=0 ); - //void StreamImagesZip( int scale=100, int maxfps=10, time_t ttl=0 ); - void SingleImage( int scale=100 ); - void SingleImageRaw( int scale=100 ); - void SingleImageZip( int scale=100 ); + static Monitor *Load( unsigned int id, bool load_zones, Purpose purpose ); + //void writeStreamImage( Image *image, struct timeval *timestamp, int scale, int mag, int x, int y ); + //void StreamImages( int scale=100, int maxfps=10, time_t ttl=0, int msq_id=0 ); + //void StreamImagesRaw( int scale=100, int maxfps=10, time_t ttl=0 ); + //void StreamImagesZip( int scale=100, int maxfps=10, time_t ttl=0 ); + void SingleImage( int scale=100 ); + void SingleImageRaw( int scale=100 ); + void SingleImageZip( int scale=100 ); #if HAVE_LIBAVCODEC - //void StreamMpeg( const char *format, int scale=100, int maxfps=10, int bitrate=100000 ); + //void StreamMpeg( const char *format, int scale=100, int maxfps=10, int bitrate=100000 ); #endif // HAVE_LIBAVCODEC }; #define MOD_ADD( var, delta, limit ) (((var)+(limit)+(delta))%(limit)) class MonitorStream : public StreamBase { -protected: - typedef struct SwapImage { - bool valid; - struct timeval timestamp; - char file_name[PATH_MAX]; - } SwapImage; + protected: + typedef struct SwapImage { + bool valid; + struct timeval timestamp; + char file_name[PATH_MAX]; + } SwapImage; -private: - SwapImage *temp_image_buffer; - int temp_image_buffer_count; - int temp_read_index; - int temp_write_index; + private: + SwapImage *temp_image_buffer; + int temp_image_buffer_count; + int temp_read_index; + int temp_write_index; -protected: - time_t ttl; + protected: + time_t ttl; -protected: - int playback_buffer; - bool delayed; + protected: + int playback_buffer; + bool delayed; - int frame_count; + int frame_count; -protected: - bool checkSwapPath( const char *path, bool create_path ); + protected: + bool checkSwapPath( const char *path, bool create_path ); - bool sendFrame( const char *filepath, struct timeval *timestamp ); - bool sendFrame( Image *image, struct timeval *timestamp ); - void processCommand( const CmdMsg *msg ); + bool sendFrame( const char *filepath, struct timeval *timestamp ); + bool sendFrame( Image *image, struct timeval *timestamp ); + void processCommand( const CmdMsg *msg ); -public: - MonitorStream() : playback_buffer( 0 ), delayed( false ), frame_count( 0 ) { - } - void setStreamBuffer( int p_playback_buffer ) { - playback_buffer = p_playback_buffer; - } - void setStreamTTL( time_t p_ttl ) { - ttl = p_ttl; - } - bool setStreamStart( int monitor_id ) { - return loadMonitor( monitor_id ); - } - void runStream(); + public: + MonitorStream() : playback_buffer( 0 ), delayed( false ), frame_count( 0 ) { + } + void setStreamBuffer( int p_playback_buffer ) { + playback_buffer = p_playback_buffer; + } + void setStreamTTL( time_t p_ttl ) { + ttl = p_ttl; + } + bool setStreamStart( int monitor_id ) { + return loadMonitor( monitor_id ); + } + void runStream(); }; #endif // ZM_MONITOR_H diff --git a/src/zm_mpeg.cpp b/src/zm_mpeg.cpp index 01f9006b8..1cdf73057 100644 --- a/src/zm_mpeg.cpp +++ b/src/zm_mpeg.cpp @@ -333,7 +333,13 @@ void VideoStream::OpenStream( ) Panic( "Could not allocate opicture" ); } +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int size = av_image_get_buffer_size( c->pix_fmt, c->width, + c->height, 1 ); +#else int size = avpicture_get_size( c->pix_fmt, c->width, c->height ); +#endif + uint8_t *opicture_buf = (uint8_t *)av_malloc( size ); if ( !opicture_buf ) { @@ -344,7 +350,13 @@ void VideoStream::OpenStream( ) #endif Panic( "Could not allocate opicture_buf" ); } - avpicture_fill( (AVPicture *)opicture, opicture_buf, c->pix_fmt, c->width, c->height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(opicture->data, opicture->linesize, + opicture_buf, c->pix_fmt, c->width, c->height, 1); +#else + avpicture_fill( (AVPicture *)opicture, opicture_buf, c->pix_fmt, + c->width, c->height ); +#endif /* if the output format is not identical to the input format, then a temporary picture is needed too. It is then converted to the required @@ -361,7 +373,12 @@ void VideoStream::OpenStream( ) { Panic( "Could not allocate tmp_opicture" ); } +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int size = av_image_get_buffer_size( pf, c->width, + c->height,1 ); +#else int size = avpicture_get_size( pf, c->width, c->height ); +#endif uint8_t *tmp_opicture_buf = (uint8_t *)av_malloc( size ); if ( !tmp_opicture_buf ) { @@ -372,7 +389,14 @@ void VideoStream::OpenStream( ) #endif Panic( "Could not allocate tmp_opicture_buf" ); } - avpicture_fill( (AVPicture *)tmp_opicture, tmp_opicture_buf, pf, c->width, c->height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(tmp_opicture->data, + tmp_opicture->linesize, tmp_opicture_buf, pf, + c->width, c->height, 1); +#else + avpicture_fill( (AVPicture *)tmp_opicture, + tmp_opicture_buf, pf, c->width, c->height ); +#endif } } @@ -678,14 +702,14 @@ double VideoStream::ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size, #endif if ( got_packet ) { - if ( c->coded_frame->key_frame ) - { -#if LIBAVCODEC_VERSION_CHECK(52, 30, 2, 30, 2) - pkt->flags |= AV_PKT_FLAG_KEY; -#else - pkt->flags |= PKT_FLAG_KEY; -#endif - } +// if ( c->coded_frame->key_frame ) +// { +//#if LIBAVCODEC_VERSION_CHECK(52, 30, 2, 30, 2) +// pkt->flags |= AV_PKT_FLAG_KEY; +//#else +// pkt->flags |= PKT_FLAG_KEY; +//#endif +// } if ( pkt->pts != (int64_t)AV_NOPTS_VALUE ) { diff --git a/src/zm_mpeg.h b/src/zm_mpeg.h index b54776e70..e2ec33592 100644 --- a/src/zm_mpeg.h +++ b/src/zm_mpeg.h @@ -27,60 +27,60 @@ class VideoStream { protected: - struct MimeData - { - const char *format; - const char *mime_type; - }; + struct MimeData + { + const char *format; + const char *mime_type; + }; protected: - static bool initialised; - static struct MimeData mime_data[]; + static bool initialised; + static struct MimeData mime_data[]; protected: - char *codec_and_format; - const char *filename; - const char *format; - const char *codec_name; - enum _AVPIXELFORMAT pf; - AVOutputFormat *of; - AVFormatContext *ofc; - AVStream *ost; - AVCodec *codec; - AVFrame *opicture; - AVFrame *tmp_opicture; - uint8_t *video_outbuf; - int video_outbuf_size; - double last_pts; - - pthread_t streaming_thread; - bool do_streaming; - uint8_t *buffer_copy; - bool add_timestamp; - unsigned int timestamp; - pthread_mutex_t *buffer_copy_lock; - int buffer_copy_size; - int buffer_copy_used; - AVPacket** packet_buffers; - int packet_index; - int SendPacket(AVPacket *packet); - static void* StreamingThreadCallback(void *ctx); + char *codec_and_format; + const char *filename; + const char *format; + const char *codec_name; + enum _AVPIXELFORMAT pf; + AVOutputFormat *of; + AVFormatContext *ofc; + AVStream *ost; + AVCodec *codec; + AVFrame *opicture; + AVFrame *tmp_opicture; + uint8_t *video_outbuf; + int video_outbuf_size; + double last_pts; + + pthread_t streaming_thread; + bool do_streaming; + uint8_t *buffer_copy; + bool add_timestamp; + unsigned int timestamp; + pthread_mutex_t *buffer_copy_lock; + int buffer_copy_size; + int buffer_copy_used; + AVPacket** packet_buffers; + int packet_index; + int SendPacket(AVPacket *packet); + static void* StreamingThreadCallback(void *ctx); protected: - static void Initialise(); + static void Initialise(); - void SetupFormat( ); - void SetupCodec( int colours, int subpixelorder, int width, int height, int bitrate, double frame_rate ); - void SetParameters(); - void ActuallyOpenStream(); - double ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size, bool add_timestamp=false, unsigned int timestamp=0 ); + void SetupFormat( ); + void SetupCodec( int colours, int subpixelorder, int width, int height, int bitrate, double frame_rate ); + void SetParameters(); + void ActuallyOpenStream(); + double ActuallyEncodeFrame( const uint8_t *buffer, int buffer_size, bool add_timestamp=false, unsigned int timestamp=0 ); public: - VideoStream( const char *filename, const char *format, int bitrate, double frame_rate, int colours, int subpixelorder, int width, int height ); - ~VideoStream(); - const char *MimeType() const; - void OpenStream(); - double EncodeFrame( const uint8_t *buffer, int buffer_size, bool add_timestamp=false, unsigned int timestamp=0 ); + VideoStream( const char *filename, const char *format, int bitrate, double frame_rate, int colours, int subpixelorder, int width, int height ); + ~VideoStream(); + const char *MimeType() const; + void OpenStream(); + double EncodeFrame( const uint8_t *buffer, int buffer_size, bool add_timestamp=false, unsigned int timestamp=0 ); }; #endif // HAVE_LIBAVCODEC diff --git a/src/zm_poly.cpp b/src/zm_poly.cpp index 4eee73f46..cddcced46 100644 --- a/src/zm_poly.cpp +++ b/src/zm_poly.cpp @@ -28,95 +28,95 @@ void Polygon::calcArea() { - double float_area = 0.0L; - for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) - { - double trap_area = ((coords[i].X()-coords[j].X())*((coords[i].Y()+coords[j].Y())))/2.0L; - float_area += trap_area; - //printf( "%.2f (%.2f)\n", float_area, trap_area ); - } - area = (int)round(fabs(float_area)); + double float_area = 0.0L; + for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) + { + double trap_area = ((coords[i].X()-coords[j].X())*((coords[i].Y()+coords[j].Y())))/2.0L; + float_area += trap_area; + //printf( "%.2f (%.2f)\n", float_area, trap_area ); + } + area = (int)round(fabs(float_area)); } void Polygon::calcCentre() { - if ( !area && n_coords ) - calcArea(); - double float_x = 0.0L, float_y = 0.0L; - for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) - { - float_x += ((coords[i].Y()-coords[j].Y())*((coords[i].X()*2)+(coords[i].X()*coords[j].X())+(coords[j].X()*2))); - float_y += ((coords[j].X()-coords[i].X())*((coords[i].Y()*2)+(coords[i].Y()*coords[j].Y())+(coords[j].Y()*2))); - } - float_x /= (6*area); - float_y /= (6*area); - //printf( "%.2f,%.2f\n", float_x, float_y ); - centre = Coord( (int)round(float_x), (int)round(float_y) ); + if ( !area && n_coords ) + calcArea(); + double float_x = 0.0L, float_y = 0.0L; + for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) + { + float_x += ((coords[i].Y()-coords[j].Y())*((coords[i].X()*2)+(coords[i].X()*coords[j].X())+(coords[j].X()*2))); + float_y += ((coords[j].X()-coords[i].X())*((coords[i].Y()*2)+(coords[i].Y()*coords[j].Y())+(coords[j].Y()*2))); + } + float_x /= (6*area); + float_y /= (6*area); + //printf( "%.2f,%.2f\n", float_x, float_y ); + centre = Coord( (int)round(float_x), (int)round(float_y) ); } Polygon::Polygon( int p_n_coords, const Coord *p_coords ) : n_coords( p_n_coords ) { - coords = new Coord[n_coords]; + coords = new Coord[n_coords]; - int min_x = -1; - int max_x = -1; - int min_y = -1; - int max_y = -1; - for( int i = 0; i < n_coords; i++ ) - { - coords[i] = p_coords[i]; - if ( min_x == -1 || coords[i].X() < min_x ) - min_x = coords[i].X(); - if ( max_x == -1 || coords[i].X() > max_x ) - max_x = coords[i].X(); - if ( min_y == -1 || coords[i].Y() < min_y ) - min_y = coords[i].Y(); - if ( max_y == -1 || coords[i].Y() > max_y ) - max_y = coords[i].Y(); - } - extent = Box( min_x, min_y, max_x, max_y ); - calcArea(); - calcCentre(); + int min_x = -1; + int max_x = -1; + int min_y = -1; + int max_y = -1; + for( int i = 0; i < n_coords; i++ ) + { + coords[i] = p_coords[i]; + if ( min_x == -1 || coords[i].X() < min_x ) + min_x = coords[i].X(); + if ( max_x == -1 || coords[i].X() > max_x ) + max_x = coords[i].X(); + if ( min_y == -1 || coords[i].Y() < min_y ) + min_y = coords[i].Y(); + if ( max_y == -1 || coords[i].Y() > max_y ) + max_y = coords[i].Y(); + } + extent = Box( min_x, min_y, max_x, max_y ); + calcArea(); + calcCentre(); } Polygon::Polygon( const Polygon &p_polygon ) : n_coords( p_polygon.n_coords ), extent( p_polygon.extent ), area( p_polygon.area ), centre( p_polygon.centre ) { - coords = new Coord[n_coords]; - for( int i = 0; i < n_coords; i++ ) - { - coords[i] = p_polygon.coords[i]; - } + coords = new Coord[n_coords]; + for( int i = 0; i < n_coords; i++ ) + { + coords[i] = p_polygon.coords[i]; + } } Polygon &Polygon::operator=( const Polygon &p_polygon ) { - if ( n_coords < p_polygon.n_coords ) - { - delete[] coords; - coords = new Coord[p_polygon.n_coords]; - } - n_coords = p_polygon.n_coords; - for( int i = 0; i < n_coords; i++ ) - { - coords[i] = p_polygon.coords[i]; - } - extent = p_polygon.extent; - area = p_polygon.area; - centre = p_polygon.centre; - return( *this ); + if ( n_coords < p_polygon.n_coords ) + { + delete[] coords; + coords = new Coord[p_polygon.n_coords]; + } + n_coords = p_polygon.n_coords; + for( int i = 0; i < n_coords; i++ ) + { + coords[i] = p_polygon.coords[i]; + } + extent = p_polygon.extent; + area = p_polygon.area; + centre = p_polygon.centre; + return( *this ); } bool Polygon::isInside( const Coord &coord ) const { - bool inside = false; - for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) - { - if ( (((coords[i].Y() <= coord.Y()) && (coord.Y() < coords[j].Y()) ) - || ((coords[j].Y() <= coord.Y()) && (coord.Y() < coords[i].Y()))) - && (coord.X() < (coords[j].X() - coords[i].X()) * (coord.Y() - coords[i].Y()) / (coords[j].Y() - coords[i].Y()) + coords[i].X())) - { - inside = !inside; - } - } - return( inside ); + bool inside = false; + for ( int i = 0, j = n_coords-1; i < n_coords; j = i++ ) + { + if ( (((coords[i].Y() <= coord.Y()) && (coord.Y() < coords[j].Y()) ) + || ((coords[j].Y() <= coord.Y()) && (coord.Y() < coords[i].Y()))) + && (coord.X() < (coords[j].X() - coords[i].X()) * (coord.Y() - coords[i].Y()) / (coords[j].Y() - coords[i].Y()) + coords[i].X())) + { + inside = !inside; + } + } + return( inside ); } diff --git a/src/zm_poly.h b/src/zm_poly.h index 854a3c322..7ba3043fd 100644 --- a/src/zm_poly.h +++ b/src/zm_poly.h @@ -33,93 +33,93 @@ class Polygon { protected: - struct Edge - { - int min_y; - int max_y; - double min_x; - double _1_m; + struct Edge + { + int min_y; + int max_y; + double min_x; + double _1_m; - static int CompareYX( const void *p1, const void *p2 ) - { - const Edge *e1 = (const Edge *)p1, *e2 = (const Edge *)p2; - if ( e1->min_y == e2->min_y ) - return( int(e1->min_x - e2->min_x) ); - else - return( int(e1->min_y - e2->min_y) ); - } - static int CompareX( const void *p1, const void *p2 ) - { - const Edge *e1 = (const Edge *)p1, *e2 = (const Edge *)p2; - return( int(e1->min_x - e2->min_x) ); - } - }; + static int CompareYX( const void *p1, const void *p2 ) + { + const Edge *e1 = (const Edge *)p1, *e2 = (const Edge *)p2; + if ( e1->min_y == e2->min_y ) + return( int(e1->min_x - e2->min_x) ); + else + return( int(e1->min_y - e2->min_y) ); + } + static int CompareX( const void *p1, const void *p2 ) + { + const Edge *e1 = (const Edge *)p1, *e2 = (const Edge *)p2; + return( int(e1->min_x - e2->min_x) ); + } + }; - struct Slice - { - int min_x; - int max_x; - int n_edges; - int *edges; + struct Slice + { + int min_x; + int max_x; + int n_edges; + int *edges; - Slice() - { - n_edges = 0; - edges = 0; - } - ~Slice() - { - delete edges; - } - }; + Slice() + { + n_edges = 0; + edges = 0; + } + ~Slice() + { + delete edges; + } + }; protected: - int n_coords; - Coord *coords; - Box extent; - int area; - Coord centre; - Edge *edges; - Slice *slices; + int n_coords; + Coord *coords; + Box extent; + int area; + Coord centre; + Edge *edges; + Slice *slices; protected: - void initialiseEdges(); - void calcArea(); - void calcCentre(); + void initialiseEdges(); + void calcArea(); + void calcCentre(); public: - inline Polygon() : n_coords( 0 ), coords( 0 ), area( 0 ) - { - } - Polygon( int p_n_coords, const Coord *p_coords ); - Polygon( const Polygon &p_polygon ); - ~Polygon() - { - delete[] coords; - } + inline Polygon() : n_coords( 0 ), coords( 0 ), area( 0 ) + { + } + Polygon( int p_n_coords, const Coord *p_coords ); + Polygon( const Polygon &p_polygon ); + ~Polygon() + { + delete[] coords; + } - Polygon &operator=( const Polygon &p_polygon ); + Polygon &operator=( const Polygon &p_polygon ); - inline int getNumCoords() const { return( n_coords ); } - inline const Coord &getCoord( int index ) const - { - return( coords[index] ); - } + inline int getNumCoords() const { return( n_coords ); } + inline const Coord &getCoord( int index ) const + { + return( coords[index] ); + } - inline const Box &Extent() const { return( extent ); } - inline int LoX() const { return( extent.LoX() ); } - inline int HiX() const { return( extent.HiX() ); } - inline int LoY() const { return( extent.LoY() ); } - inline int HiY() const { return( extent.HiY() ); } - inline int Width() const { return( extent.Width() ); } - inline int Height() const { return( extent.Height() ); } + inline const Box &Extent() const { return( extent ); } + inline int LoX() const { return( extent.LoX() ); } + inline int HiX() const { return( extent.HiX() ); } + inline int LoY() const { return( extent.LoY() ); } + inline int HiY() const { return( extent.HiY() ); } + inline int Width() const { return( extent.Width() ); } + inline int Height() const { return( extent.Height() ); } - inline int Area() const { return( area ); } - inline const Coord &Centre() const - { - return( centre ); - } - bool isInside( const Coord &coord ) const; + inline int Area() const { return( area ); } + inline const Coord &Centre() const + { + return( centre ); + } + bool isInside( const Coord &coord ) const; }; #endif // ZM_POLY_H diff --git a/src/zm_regexp.cpp b/src/zm_regexp.cpp index 43f738217..cfa686688 100644 --- a/src/zm_regexp.cpp +++ b/src/zm_regexp.cpp @@ -26,99 +26,99 @@ RegExpr::RegExpr( const char *pattern, int flags, int p_max_matches ) : max_matches( p_max_matches ), match_buffers( 0 ), match_lengths( 0 ), match_valid( 0 ) { - const char *errstr; - int erroffset = 0; - if ( !(regex = pcre_compile( pattern, flags, &errstr, &erroffset, 0 )) ) - { - Panic( "pcre_compile(%s): %s at %d", pattern, errstr, erroffset ); - } + const char *errstr; + int erroffset = 0; + if ( !(regex = pcre_compile( pattern, flags, &errstr, &erroffset, 0 )) ) + { + Panic( "pcre_compile(%s): %s at %d", pattern, errstr, erroffset ); + } - regextra = pcre_study( regex, 0, &errstr ); - if ( errstr ) - { - Panic( "pcre_study(%s): %s", pattern, errstr ); - } + regextra = pcre_study( regex, 0, &errstr ); + if ( errstr ) + { + Panic( "pcre_study(%s): %s", pattern, errstr ); + } - if ( (ok = (bool)regex) ) - { - match_vectors = new int[3*max_matches]; - memset( match_vectors, 0, sizeof(*match_vectors)*3*max_matches ); - match_buffers = new char *[max_matches]; - memset( match_buffers, 0, sizeof(*match_buffers)*max_matches ); - match_lengths = new int[max_matches]; - memset( match_lengths, 0, sizeof(*match_lengths)*max_matches ); - match_valid = new bool[max_matches]; - memset( match_valid, 0, sizeof(*match_valid)*max_matches ); - } - n_matches = 0; + if ( (ok = (bool)regex) ) + { + match_vectors = new int[3*max_matches]; + memset( match_vectors, 0, sizeof(*match_vectors)*3*max_matches ); + match_buffers = new char *[max_matches]; + memset( match_buffers, 0, sizeof(*match_buffers)*max_matches ); + match_lengths = new int[max_matches]; + memset( match_lengths, 0, sizeof(*match_lengths)*max_matches ); + match_valid = new bool[max_matches]; + memset( match_valid, 0, sizeof(*match_valid)*max_matches ); + } + n_matches = 0; } RegExpr::~RegExpr() { - for ( int i = 0; i < max_matches; i++ ) - { - if ( match_buffers[i] ) - { - delete[] match_buffers[i]; - } - } - delete[] match_valid; - delete[] match_lengths; - delete[] match_buffers; - delete[] match_vectors; + for ( int i = 0; i < max_matches; i++ ) + { + if ( match_buffers[i] ) + { + delete[] match_buffers[i]; + } + } + delete[] match_valid; + delete[] match_lengths; + delete[] match_buffers; + delete[] match_vectors; } int RegExpr::Match( const char *subject_string, int subject_length, int flags ) { - match_string = subject_string; + match_string = subject_string; - n_matches = pcre_exec( regex, regextra, subject_string, subject_length, 0, flags, match_vectors, 2*max_matches ); + n_matches = pcre_exec( regex, regextra, subject_string, subject_length, 0, flags, match_vectors, 2*max_matches ); - if ( n_matches <= 0 ) - { - if ( n_matches < PCRE_ERROR_NOMATCH ) - { - Error( "Error %d executing regular expression", n_matches ); - } - return( n_matches = 0 ); - } + if ( n_matches <= 0 ) + { + if ( n_matches < PCRE_ERROR_NOMATCH ) + { + Error( "Error %d executing regular expression", n_matches ); + } + return( n_matches = 0 ); + } - for( int i = 0; i < max_matches; i++ ) - { - match_valid[i] = false; - } - return( n_matches ); + for( int i = 0; i < max_matches; i++ ) + { + match_valid[i] = false; + } + return( n_matches ); } const char *RegExpr::MatchString( int match_index ) const { - if ( match_index > n_matches ) - { - return( 0 ); - } - if ( !match_valid[match_index] ) - { - int match_len = match_vectors[(2*match_index)+1]-match_vectors[2*match_index]; - if ( match_lengths[match_index] < (match_len+1) ) - { - delete[] match_buffers[match_index]; - match_buffers[match_index] = new char[match_len+1]; - match_lengths[match_index] = match_len+1; - } - memcpy( match_buffers[match_index], match_string+match_vectors[2*match_index], match_len ); - match_buffers[match_index][match_len] = '\0'; - match_valid[match_index] = true; - } - return( match_buffers[match_index] ); + if ( match_index > n_matches ) + { + return( 0 ); + } + if ( !match_valid[match_index] ) + { + int match_len = match_vectors[(2*match_index)+1]-match_vectors[2*match_index]; + if ( match_lengths[match_index] < (match_len+1) ) + { + delete[] match_buffers[match_index]; + match_buffers[match_index] = new char[match_len+1]; + match_lengths[match_index] = match_len+1; + } + memcpy( match_buffers[match_index], match_string+match_vectors[2*match_index], match_len ); + match_buffers[match_index][match_len] = '\0'; + match_valid[match_index] = true; + } + return( match_buffers[match_index] ); } int RegExpr::MatchLength( int match_index ) const { - if ( match_index > n_matches ) - { - return( 0 ); - } - return( match_vectors[(2*match_index)+1]-match_vectors[2*match_index] ); + if ( match_index > n_matches ) + { + return( 0 ); + } + return( match_vectors[(2*match_index)+1]-match_vectors[2*match_index] ); } #endif // HAVE_LIBPCRE diff --git a/src/zm_regexp.h b/src/zm_regexp.h index f1c9d705d..1b1a9d518 100644 --- a/src/zm_regexp.h +++ b/src/zm_regexp.h @@ -35,29 +35,29 @@ class RegExpr { protected: - pcre *regex; - pcre_extra *regextra; - int max_matches; - int *match_vectors; - mutable char **match_buffers; - int *match_lengths; - bool *match_valid; + pcre *regex; + pcre_extra *regextra; + int max_matches; + int *match_vectors; + mutable char **match_buffers; + int *match_lengths; + bool *match_valid; protected: - const char *match_string; - int n_matches; - + const char *match_string; + int n_matches; + protected: - bool ok; + bool ok; public: - RegExpr( const char *pattern, int cflags=0, int p_max_matches=32 ); - ~RegExpr(); - bool Ok() const { return( ok ); } - int MatchCount() const { return( n_matches ); } - int Match( const char *subject_string, int subject_length, int flags=0 ); - const char *MatchString( int match_index ) const; - int MatchLength( int match_index ) const; + RegExpr( const char *pattern, int cflags=0, int p_max_matches=32 ); + ~RegExpr(); + bool Ok() const { return( ok ); } + int MatchCount() const { return( n_matches ); } + int Match( const char *subject_string, int subject_length, int flags=0 ); + const char *MatchString( int match_index ) const; + int MatchLength( int match_index ) const; }; #endif // HAVE_LIBPCRE diff --git a/src/zm_remote_camera_rtsp.cpp b/src/zm_remote_camera_rtsp.cpp index 418cea6f8..5256b1de2 100644 --- a/src/zm_remote_camera_rtsp.cpp +++ b/src/zm_remote_camera_rtsp.cpp @@ -238,13 +238,18 @@ int RemoteCameraRtsp::PrimeCapture() mFrame = avcodec_alloc_frame(); #endif - if(mRawFrame == NULL || mFrame == NULL) - Fatal( "Unable to allocate frame(s)"); - + if(mRawFrame == NULL || mFrame == NULL) + Fatal( "Unable to allocate frame(s)"); + +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + int pSize = av_image_get_buffer_size( imagePixFormat, width, height, 1 ); +#else int pSize = avpicture_get_size( imagePixFormat, width, height ); - if( (unsigned int)pSize != imagesize) { - Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); - } +#endif + + if( (unsigned int)pSize != imagesize) { + Fatal("Image size mismatch. Required: %d Available: %d",pSize,imagesize); + } /* #if HAVE_LIBSWSCALE if(!sws_isSupportedInput(mCodecContext->pix_fmt)) { @@ -299,24 +304,6 @@ int RemoteCameraRtsp::Capture( Image &image ) { if ( !buffer.size() ) return( -1 ); -int avResult = av_read_frame( mFormatContext, &packet ); - if ( avResult < 0 ) { - char errbuf[AV_ERROR_MAX_STRING_SIZE]; - av_strerror(avResult, errbuf, AV_ERROR_MAX_STRING_SIZE); - if ( - // Check if EOF. - (avResult == AVERROR_EOF || (mFormatContext->pb && mFormatContext->pb->eof_reached)) || - // Check for Connection failure. - (avResult == -110) - ) { - Info( "av_read_frame returned \"%s\". Reopening stream.", errbuf); - //ReopenFfmpeg(); - } - - Error( "Unable to read packet from stream %d: error %d \"%s\".", packet.stream_index, avResult, errbuf ); - return( -1 ); - } - if(mCodecContext->codec_id == AV_CODEC_ID_H264) { // SPS and PPS frames should be saved and appended to IDR frames int nalType = (buffer.head()[3] & 0x1f); @@ -339,6 +326,8 @@ int avResult = av_read_frame( mFormatContext, &packet ); buffer += lastSps; buffer += lastPps; } + } else { + Debug(3, "Not an h264 packet"); } av_init_packet( &packet ); @@ -498,9 +487,15 @@ int RemoteCameraRtsp::CaptureAndRecord( Image &image, bool recording, char* even Debug( 3, "Got frame %d", frameCount ); - avpicture_fill( (AVPicture *)mFrame, directbuffer, imagePixFormat, width, height ); +#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) + av_image_fill_arrays(mFrame->data, mFrame->linesize, + directbuffer, imagePixFormat, width, height, 1); +#else + avpicture_fill( (AVPicture *)mFrame, directbuffer, + imagePixFormat, width, height); +#endif - //Video recording + //Video recording if ( recording && !wasRecording ) { //Instantiate the video storage module diff --git a/src/zm_rgb.h b/src/zm_rgb.h index bfef10501..af74d872b 100644 --- a/src/zm_rgb.h +++ b/src/zm_rgb.h @@ -20,80 +20,80 @@ #ifndef ZM_RGB_H #define ZM_RGB_H -typedef uint32_t Rgb; // RGB colour type +typedef uint32_t Rgb; // RGB colour type -#define WHITE 0xff -#define WHITE_R 0xff -#define WHITE_G 0xff -#define WHITE_B 0xff +#define WHITE 0xff +#define WHITE_R 0xff +#define WHITE_G 0xff +#define WHITE_B 0xff -#define BLACK 0x00 -#define BLACK_R 0x00 -#define BLACK_G 0x00 -#define BLACK_B 0x00 +#define BLACK 0x00 +#define BLACK_R 0x00 +#define BLACK_G 0x00 +#define BLACK_B 0x00 -#define RGB_WHITE (0x00ffffff) -#define RGB_BLACK (0x00000000) -#define RGB_RED (0x000000ff) -#define RGB_GREEN (0x0000ff00) -#define RGB_BLUE (0x00ff0000) -#define RGB_ORANGE (0x0000a5ff) -#define RGB_PURPLE (0x00800080) -#define RGB_TRANSPARENT (0x01000000) +#define RGB_WHITE (0x00ffffff) +#define RGB_BLACK (0x00000000) +#define RGB_RED (0x000000ff) +#define RGB_GREEN (0x0000ff00) +#define RGB_BLUE (0x00ff0000) +#define RGB_ORANGE (0x0000a5ff) +#define RGB_PURPLE (0x00800080) +#define RGB_TRANSPARENT (0x01000000) -#define RGB_VAL(v,c) (((v)>>(16-((c)*8)))&0xff) +#define RGB_VAL(v,c) (((v)>>(16-((c)*8)))&0xff) /* RGB or RGBA macros */ -#define BLUE_VAL_RGBA(v) (((v)>>16)&0xff) -#define GREEN_VAL_RGBA(v) (((v)>>8)&0xff) -#define RED_VAL_RGBA(v) ((v)&0xff) -#define ALPHA_VAL_RGBA(v) ((v)>>24)&0xff) -#define RED_PTR_RGBA(ptr) (*((uint8_t*)ptr)) -#define GREEN_PTR_RGBA(ptr) (*((uint8_t*)ptr+1)) -#define BLUE_PTR_RGBA(ptr) (*((uint8_t*)ptr+2)) -#define ALPHA_PTR_RGBA(ptr) (*((uint8_t*)ptr+3)) +#define BLUE_VAL_RGBA(v) (((v)>>16)&0xff) +#define GREEN_VAL_RGBA(v) (((v)>>8)&0xff) +#define RED_VAL_RGBA(v) ((v)&0xff) +#define ALPHA_VAL_RGBA(v) ((v)>>24)&0xff) +#define RED_PTR_RGBA(ptr) (*((uint8_t*)ptr)) +#define GREEN_PTR_RGBA(ptr) (*((uint8_t*)ptr+1)) +#define BLUE_PTR_RGBA(ptr) (*((uint8_t*)ptr+2)) +#define ALPHA_PTR_RGBA(ptr) (*((uint8_t*)ptr+3)) /* BGR or BGRA */ -#define RED_VAL_BGRA(v) (((v)>>16)&0xff) -#define GREEN_VAL_BGRA(v) (((v)>>8)&0xff) -#define BLUE_VAL_BGRA(v) ((v)&0xff) -#define ALPHA_VAL_BGRA(v) ((v)>>24)&0xff) -#define RED_PTR_BGRA(ptr) (*((uint8_t*)ptr+2)) -#define GREEN_PTR_BGRA(ptr) (*((uint8_t*)ptr+1)) -#define BLUE_PTR_BGRA(ptr) (*((uint8_t*)ptr)) -#define ALPHA_PTR_BGRA(ptr) (*((uint8_t*)ptr+3)) +#define RED_VAL_BGRA(v) (((v)>>16)&0xff) +#define GREEN_VAL_BGRA(v) (((v)>>8)&0xff) +#define BLUE_VAL_BGRA(v) ((v)&0xff) +#define ALPHA_VAL_BGRA(v) ((v)>>24)&0xff) +#define RED_PTR_BGRA(ptr) (*((uint8_t*)ptr+2)) +#define GREEN_PTR_BGRA(ptr) (*((uint8_t*)ptr+1)) +#define BLUE_PTR_BGRA(ptr) (*((uint8_t*)ptr)) +#define ALPHA_PTR_BGRA(ptr) (*((uint8_t*)ptr+3)) /* ARGB */ -#define BLUE_VAL_ARGB(v) (((v)>>24)&0xff) -#define GREEN_VAL_ARGB(v) (((v)>>16)&0xff) -#define RED_VAL_ARGB(v) (((v)>>8)&0xff) -#define ALPHA_VAL_ARGB(v) ((v)&0xff) -#define RED_PTR_ARGB(ptr) (*((uint8_t*)ptr+1)) -#define GREEN_PTR_ARGB(ptr) (*((uint8_t*)ptr+2)) -#define BLUE_PTR_ARGB(ptr) (*((uint8_t*)ptr+3)) -#define ALPHA_PTR_ARGB(ptr) (*((uint8_t*)ptr)) +#define BLUE_VAL_ARGB(v) (((v)>>24)&0xff) +#define GREEN_VAL_ARGB(v) (((v)>>16)&0xff) +#define RED_VAL_ARGB(v) (((v)>>8)&0xff) +#define ALPHA_VAL_ARGB(v) ((v)&0xff) +#define RED_PTR_ARGB(ptr) (*((uint8_t*)ptr+1)) +#define GREEN_PTR_ARGB(ptr) (*((uint8_t*)ptr+2)) +#define BLUE_PTR_ARGB(ptr) (*((uint8_t*)ptr+3)) +#define ALPHA_PTR_ARGB(ptr) (*((uint8_t*)ptr)) /* ABGR */ -#define BLUE_VAL_ABGR(v) (((v)>>8)&0xff) -#define GREEN_VAL_ABGR(v) (((v)>>16)&0xff) -#define RED_VAL_ABGR(v) (((v)>>24)&0xff) -#define ALPHA_VAL_ABGR(v) ((v)&0xff) -#define RED_PTR_ABGR(ptr) (*((uint8_t*)ptr+3)) -#define GREEN_PTR_ABGR(ptr) (*((uint8_t*)ptr+2)) -#define BLUE_PTR_ABGR(ptr) (*((uint8_t*)ptr+1)) -#define ALPHA_PTR_ABGR(ptr) (*((uint8_t*)ptr)) +#define BLUE_VAL_ABGR(v) (((v)>>8)&0xff) +#define GREEN_VAL_ABGR(v) (((v)>>16)&0xff) +#define RED_VAL_ABGR(v) (((v)>>24)&0xff) +#define ALPHA_VAL_ABGR(v) ((v)&0xff) +#define RED_PTR_ABGR(ptr) (*((uint8_t*)ptr+3)) +#define GREEN_PTR_ABGR(ptr) (*((uint8_t*)ptr+2)) +#define BLUE_PTR_ABGR(ptr) (*((uint8_t*)ptr+1)) +#define ALPHA_PTR_ABGR(ptr) (*((uint8_t*)ptr)) -#define RGBA_BGRA_ZEROALPHA(v) ((v)&0x00ffffff) -#define ARGB_ABGR_ZEROALPHA(v) ((v)&0xffffff00) +#define RGBA_BGRA_ZEROALPHA(v) ((v)&0x00ffffff) +#define ARGB_ABGR_ZEROALPHA(v) ((v)&0xffffff00) /* ITU-R BT.709: Y = (0.2126 * R) + (0.7152 * G) + (0.0722 * B) */ /* ITU-R BT.601: Y = (0.299 * R) + (0.587 * G) + (0.114 * B) */ /* The formulas below produce an almost identical result to the weighted algorithms from the ITU-R BT.601 standard and the newer ITU-R BT.709 standard, but a lot faster */ -// #define RGB_FASTLUM_SINGLE_ITU709(v) ((RED(v)+RED(v)+BLUE(v)+GREEN(v)+GREEN(v)+GREEN(v)+GREEN(v)+GREEN(v))>>3) -// #define RGB_FASTLUM_VALUES_ITU709(ra,ga,ba) (((ra)+(ra)+(ba)+(ga)+(ga)+(ga)+(ga)+(ga))>>3) -// #define RGB_FASTLUM_SINGLE_ITU601(v) ((RED(v)+RED(v)+RED(v)+BLUE(v)+GREEN(v)+GREEN(v)+GREEN(v)+GREEN(v))>>3) -// #define RGB_FASTLUM_VALUES_ITU601(ra,ga,ba) (((ra)+(ra)+(ra)+(ba)+(ga)+(ga)+(ga)+(ga))>>3) +// #define RGB_FASTLUM_SINGLE_ITU709(v) ((RED(v)+RED(v)+BLUE(v)+GREEN(v)+GREEN(v)+GREEN(v)+GREEN(v)+GREEN(v))>>3) +// #define RGB_FASTLUM_VALUES_ITU709(ra,ga,ba) (((ra)+(ra)+(ba)+(ga)+(ga)+(ga)+(ga)+(ga))>>3) +// #define RGB_FASTLUM_SINGLE_ITU601(v) ((RED(v)+RED(v)+RED(v)+BLUE(v)+GREEN(v)+GREEN(v)+GREEN(v)+GREEN(v))>>3) +// #define RGB_FASTLUM_VALUES_ITU601(ra,ga,ba) (((ra)+(ra)+(ra)+(ba)+(ga)+(ga)+(ga)+(ga))>>3) /* ZM colours */ #define ZM_COLOUR_RGB32 4 @@ -112,46 +112,46 @@ typedef uint32_t Rgb; // RGB colour type /* A macro to use default subpixel order for a specified colour. */ /* for grayscale it will use NONE, for 3 colours it will use R,G,B, for 4 colours it will use R,G,B,A */ -#define ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(c) ((c)<<1) +#define ZM_SUBPIX_ORDER_DEFAULT_FOR_COLOUR(c) ((c)<<1) /* Convert RGB colour value into BGR\ARGB\ABGR */ inline Rgb rgb_convert(Rgb p_col, int p_subpixorder) { - Rgb result; - - switch(p_subpixorder) { - - case ZM_SUBPIX_ORDER_BGR: - case ZM_SUBPIX_ORDER_BGRA: - { - BLUE_PTR_BGRA(&result) = BLUE_VAL_RGBA(p_col); - GREEN_PTR_BGRA(&result) = GREEN_VAL_RGBA(p_col); - RED_PTR_BGRA(&result) = RED_VAL_RGBA(p_col); - } - break; - case ZM_SUBPIX_ORDER_ARGB: - { - BLUE_PTR_ARGB(&result) = BLUE_VAL_RGBA(p_col); - GREEN_PTR_ARGB(&result) = GREEN_VAL_RGBA(p_col); - RED_PTR_ARGB(&result) = RED_VAL_RGBA(p_col); - } - break; - case ZM_SUBPIX_ORDER_ABGR: - { - BLUE_PTR_ABGR(&result) = BLUE_VAL_RGBA(p_col); - GREEN_PTR_ABGR(&result) = GREEN_VAL_RGBA(p_col); - RED_PTR_ABGR(&result) = RED_VAL_RGBA(p_col); - } - break; - /* Grayscale */ - case ZM_SUBPIX_ORDER_NONE: - result = p_col & 0xff; - break; - default: - return p_col; - break; - } - - return result; + Rgb result; + + switch(p_subpixorder) { + + case ZM_SUBPIX_ORDER_BGR: + case ZM_SUBPIX_ORDER_BGRA: + { + BLUE_PTR_BGRA(&result) = BLUE_VAL_RGBA(p_col); + GREEN_PTR_BGRA(&result) = GREEN_VAL_RGBA(p_col); + RED_PTR_BGRA(&result) = RED_VAL_RGBA(p_col); + } + break; + case ZM_SUBPIX_ORDER_ARGB: + { + BLUE_PTR_ARGB(&result) = BLUE_VAL_RGBA(p_col); + GREEN_PTR_ARGB(&result) = GREEN_VAL_RGBA(p_col); + RED_PTR_ARGB(&result) = RED_VAL_RGBA(p_col); + } + break; + case ZM_SUBPIX_ORDER_ABGR: + { + BLUE_PTR_ABGR(&result) = BLUE_VAL_RGBA(p_col); + GREEN_PTR_ABGR(&result) = GREEN_VAL_RGBA(p_col); + RED_PTR_ABGR(&result) = RED_VAL_RGBA(p_col); + } + break; + /* Grayscale */ + case ZM_SUBPIX_ORDER_NONE: + result = p_col & 0xff; + break; + default: + return p_col; + break; + } + + return result; } #endif // ZM_RGB_H diff --git a/src/zm_rtp_ctrl.cpp b/src/zm_rtp_ctrl.cpp index 1a0604137..5ff23b31d 100644 --- a/src/zm_rtp_ctrl.cpp +++ b/src/zm_rtp_ctrl.cpp @@ -34,343 +34,343 @@ RtpCtrlThread::RtpCtrlThread( RtspThread &rtspThread, RtpSource &rtpSource ) : m int RtpCtrlThread::recvPacket( const unsigned char *packet, ssize_t packetLen ) { - const RtcpPacket *rtcpPacket; - rtcpPacket = (RtcpPacket *)packet; + const RtcpPacket *rtcpPacket; + rtcpPacket = (RtcpPacket *)packet; - int consumed = 0; + int consumed = 0; - //printf( "C: " ); - //for ( int i = 0; i < packetLen; i++ ) - //printf( "%02x ", (unsigned char)packet[i] ); - //printf( "\n" ); - int ver = rtcpPacket->header.version; - int count = rtcpPacket->header.count; - int pt = rtcpPacket->header.pt; - int len = ntohs(rtcpPacket->header.lenN); + //printf( "C: " ); + //for ( int i = 0; i < packetLen; i++ ) + //printf( "%02x ", (unsigned char)packet[i] ); + //printf( "\n" ); + int ver = rtcpPacket->header.version; + int count = rtcpPacket->header.count; + int pt = rtcpPacket->header.pt; + int len = ntohs(rtcpPacket->header.lenN); - Debug( 5, "RTCP Ver: %d", ver ); - Debug( 5, "RTCP Count: %d", count ); - Debug( 5, "RTCP Pt: %d", pt ); - Debug( 5, "RTCP len: %d", len ); + Debug( 5, "RTCP Ver: %d", ver ); + Debug( 5, "RTCP Count: %d", count ); + Debug( 5, "RTCP Pt: %d", pt ); + Debug( 5, "RTCP len: %d", len ); - switch( pt ) + switch( pt ) + { + case RTCP_SR : { - case RTCP_SR : - { - uint32_t ssrc = ntohl(rtcpPacket->body.sr.ssrcN); + uint32_t ssrc = ntohl(rtcpPacket->body.sr.ssrcN); - Debug( 5, "RTCP Got SR (%x)", ssrc ); - if ( mRtpSource.getSsrc() ) - { - if ( ssrc != mRtpSource.getSsrc() ) - { - Warning( "Discarding packet for unrecognised ssrc %x", ssrc ); - return( -1 ); - } - } - else if ( ssrc ) - { - mRtpSource.setSsrc( ssrc ); - } + Debug( 5, "RTCP Got SR (%x)", ssrc ); + if ( mRtpSource.getSsrc() ) + { + if ( ssrc != mRtpSource.getSsrc() ) + { + Warning( "Discarding packet for unrecognised ssrc %x", ssrc ); + return( -1 ); + } + } + else if ( ssrc ) + { + mRtpSource.setSsrc( ssrc ); + } - if ( len > 1 ) - { - //printf( "NTPts:%d.%d, RTPts:%d\n", $ntptsmsb, $ntptslsb, $rtpts ); - uint16_t ntptsmsb = ntohl(rtcpPacket->body.sr.ntpSecN); - uint16_t ntptslsb = ntohl(rtcpPacket->body.sr.ntpFracN); - //printf( "NTPts:%x.%04x, RTPts:%x\n", $ntptsmsb, $ntptslsb, $rtpts ); - //printf( "Pkts:$sendpkts, Octs:$sendocts\n" ); - uint32_t rtpTime = ntohl(rtcpPacket->body.sr.rtpTsN); + if ( len > 1 ) + { + //printf( "NTPts:%d.%d, RTPts:%d\n", $ntptsmsb, $ntptslsb, $rtpts ); + uint16_t ntptsmsb = ntohl(rtcpPacket->body.sr.ntpSecN); + uint16_t ntptslsb = ntohl(rtcpPacket->body.sr.ntpFracN); + //printf( "NTPts:%x.%04x, RTPts:%x\n", $ntptsmsb, $ntptslsb, $rtpts ); + //printf( "Pkts:$sendpkts, Octs:$sendocts\n" ); + uint32_t rtpTime = ntohl(rtcpPacket->body.sr.rtpTsN); - mRtpSource.updateRtcpData( ntptsmsb, ntptslsb, rtpTime ); - } - break; - } - case RTCP_SDES : - { - ssize_t contentLen = packetLen - sizeof(rtcpPacket->header); - while ( contentLen ) - { - Debug( 5, "RTCP CL: %zd", contentLen ); - uint32_t ssrc = ntohl(rtcpPacket->body.sdes.srcN); - - Debug( 5, "RTCP Got SDES (%x), %d items", ssrc, count ); - if ( mRtpSource.getSsrc() && (ssrc != mRtpSource.getSsrc()) ) - { - Warning( "Discarding packet for unrecognised ssrc %x", ssrc ); - return( -1 ); - } - - unsigned char *sdesPtr = (unsigned char *)&rtcpPacket->body.sdes.item; - for ( int i = 0; i < count; i++ ) - { - RtcpSdesItem *item = (RtcpSdesItem *)sdesPtr; - Debug( 5, "RTCP Item length %d", item->len ); - switch( item->type ) - { - case RTCP_SDES_CNAME : - { - std::string cname( item->data, item->len ); - Debug( 5, "RTCP Got CNAME %s", cname.c_str() ); - break; - } - case RTCP_SDES_END : - case RTCP_SDES_NAME : - case RTCP_SDES_EMAIL : - case RTCP_SDES_PHONE : - case RTCP_SDES_LOC : - case RTCP_SDES_TOOL : - case RTCP_SDES_NOTE : - case RTCP_SDES_PRIV : - default : - { - Error( "Received unexpected SDES item type %d, ignoring", item->type ); - return( -1 ); - } - } - int paddedLen = 4+2+item->len+1; // Add null byte - paddedLen = (((paddedLen-1)/4)+1)*4; // Round to nearest multiple of 4 - Debug( 5, "RTCP PL:%d", paddedLen ); - sdesPtr += paddedLen; - contentLen = ( paddedLen <= contentLen ) ? ( contentLen - paddedLen ) : 0; - } - } - break; - } - case RTCP_BYE : - { - Debug( 5, "RTCP Got BYE" ); - mStop = true; - break; - } - case RTCP_APP : - { - // Ignoring as per RFC 3550 - Debug( 5, "Received RTCP_APP packet, ignoring."); - break; - } - case RTCP_RR : - { - Error( "Received RTCP_RR packet." ); - return( -1 ); - } - default : - { - // Ignore unknown packet types. Some cameras do this by design. - Debug( 5, "Received unexpected packet type %d, ignoring", pt ); - break; - } + mRtpSource.updateRtcpData( ntptsmsb, ntptslsb, rtpTime ); + } + break; } - consumed = sizeof(uint32_t)*(len+1); - return( consumed ); + case RTCP_SDES : + { + ssize_t contentLen = packetLen - sizeof(rtcpPacket->header); + while ( contentLen ) + { + Debug( 5, "RTCP CL: %zd", contentLen ); + uint32_t ssrc = ntohl(rtcpPacket->body.sdes.srcN); + + Debug( 5, "RTCP Got SDES (%x), %d items", ssrc, count ); + if ( mRtpSource.getSsrc() && (ssrc != mRtpSource.getSsrc()) ) + { + Warning( "Discarding packet for unrecognised ssrc %x", ssrc ); + return( -1 ); + } + + unsigned char *sdesPtr = (unsigned char *)&rtcpPacket->body.sdes.item; + for ( int i = 0; i < count; i++ ) + { + RtcpSdesItem *item = (RtcpSdesItem *)sdesPtr; + Debug( 5, "RTCP Item length %d", item->len ); + switch( item->type ) + { + case RTCP_SDES_CNAME : + { + std::string cname( item->data, item->len ); + Debug( 5, "RTCP Got CNAME %s", cname.c_str() ); + break; + } + case RTCP_SDES_END : + case RTCP_SDES_NAME : + case RTCP_SDES_EMAIL : + case RTCP_SDES_PHONE : + case RTCP_SDES_LOC : + case RTCP_SDES_TOOL : + case RTCP_SDES_NOTE : + case RTCP_SDES_PRIV : + default : + { + Error( "Received unexpected SDES item type %d, ignoring", item->type ); + return( -1 ); + } + } + int paddedLen = 4+2+item->len+1; // Add null byte + paddedLen = (((paddedLen-1)/4)+1)*4; // Round to nearest multiple of 4 + Debug( 5, "RTCP PL:%d", paddedLen ); + sdesPtr += paddedLen; + contentLen = ( paddedLen <= contentLen ) ? ( contentLen - paddedLen ) : 0; + } + } + break; + } + case RTCP_BYE : + { + Debug( 5, "RTCP Got BYE" ); + mStop = true; + break; + } + case RTCP_APP : + { + // Ignoring as per RFC 3550 + Debug( 5, "Received RTCP_APP packet, ignoring."); + break; + } + case RTCP_RR : + { + Error( "Received RTCP_RR packet." ); + return( -1 ); + } + default : + { + // Ignore unknown packet types. Some cameras do this by design. + Debug( 5, "Received unexpected packet type %d, ignoring", pt ); + break; + } + } + consumed = sizeof(uint32_t)*(len+1); + return( consumed ); } int RtpCtrlThread::generateRr( const unsigned char *packet, ssize_t packetLen ) { - RtcpPacket *rtcpPacket = (RtcpPacket *)packet; + RtcpPacket *rtcpPacket = (RtcpPacket *)packet; - int byteLen = sizeof(rtcpPacket->header)+sizeof(rtcpPacket->body.rr)+sizeof(rtcpPacket->body.rr.rr[0]); - int wordLen = ((byteLen-1)/sizeof(uint32_t))+1; + int byteLen = sizeof(rtcpPacket->header)+sizeof(rtcpPacket->body.rr)+sizeof(rtcpPacket->body.rr.rr[0]); + int wordLen = ((byteLen-1)/sizeof(uint32_t))+1; - rtcpPacket->header.version = RTP_VERSION; - rtcpPacket->header.p = 0; - rtcpPacket->header.pt = RTCP_RR; - rtcpPacket->header.count = 1; - rtcpPacket->header.lenN = htons(wordLen-1); + rtcpPacket->header.version = RTP_VERSION; + rtcpPacket->header.p = 0; + rtcpPacket->header.pt = RTCP_RR; + rtcpPacket->header.count = 1; + rtcpPacket->header.lenN = htons(wordLen-1); - mRtpSource.updateRtcpStats(); + mRtpSource.updateRtcpStats(); - Debug( 5, "Ssrc = %d", mRtspThread.getSsrc()+1 ); - Debug( 5, "Ssrc_1 = %d", mRtpSource.getSsrc() ); - Debug( 5, "Last Seq = %d", mRtpSource.getMaxSeq() ); - Debug( 5, "Jitter = %d", mRtpSource.getJitter() ); - Debug( 5, "Last SR = %d", mRtpSource.getLastSrTimestamp() ); + Debug( 5, "Ssrc = %d", mRtspThread.getSsrc()+1 ); + Debug( 5, "Ssrc_1 = %d", mRtpSource.getSsrc() ); + Debug( 5, "Last Seq = %d", mRtpSource.getMaxSeq() ); + Debug( 5, "Jitter = %d", mRtpSource.getJitter() ); + Debug( 5, "Last SR = %d", mRtpSource.getLastSrTimestamp() ); - rtcpPacket->body.rr.ssrcN = htonl(mRtspThread.getSsrc()+1); - rtcpPacket->body.rr.rr[0].ssrcN = htonl(mRtpSource.getSsrc()); - rtcpPacket->body.rr.rr[0].lost = mRtpSource.getLostPackets(); - rtcpPacket->body.rr.rr[0].fraction = mRtpSource.getLostFraction(); - rtcpPacket->body.rr.rr[0].lastSeqN = htonl(mRtpSource.getMaxSeq()); - rtcpPacket->body.rr.rr[0].jitterN = htonl(mRtpSource.getJitter()); - rtcpPacket->body.rr.rr[0].lsrN = htonl(mRtpSource.getLastSrTimestamp()); - rtcpPacket->body.rr.rr[0].dlsrN = 0; + rtcpPacket->body.rr.ssrcN = htonl(mRtspThread.getSsrc()+1); + rtcpPacket->body.rr.rr[0].ssrcN = htonl(mRtpSource.getSsrc()); + rtcpPacket->body.rr.rr[0].lost = mRtpSource.getLostPackets(); + rtcpPacket->body.rr.rr[0].fraction = mRtpSource.getLostFraction(); + rtcpPacket->body.rr.rr[0].lastSeqN = htonl(mRtpSource.getMaxSeq()); + rtcpPacket->body.rr.rr[0].jitterN = htonl(mRtpSource.getJitter()); + rtcpPacket->body.rr.rr[0].lsrN = htonl(mRtpSource.getLastSrTimestamp()); + rtcpPacket->body.rr.rr[0].dlsrN = 0; - return( wordLen*sizeof(uint32_t) ); + return( wordLen*sizeof(uint32_t) ); } int RtpCtrlThread::generateSdes( const unsigned char *packet, ssize_t packetLen ) { - RtcpPacket *rtcpPacket = (RtcpPacket *)packet; + RtcpPacket *rtcpPacket = (RtcpPacket *)packet; - const std::string &cname = mRtpSource.getCname(); + const std::string &cname = mRtpSource.getCname(); - int byteLen = sizeof(rtcpPacket->header)+sizeof(rtcpPacket->body.sdes)+sizeof(rtcpPacket->body.sdes.item[0])+cname.size(); - int wordLen = ((byteLen-1)/sizeof(uint32_t))+1; + int byteLen = sizeof(rtcpPacket->header)+sizeof(rtcpPacket->body.sdes)+sizeof(rtcpPacket->body.sdes.item[0])+cname.size(); + int wordLen = ((byteLen-1)/sizeof(uint32_t))+1; - rtcpPacket->header.version = RTP_VERSION; - rtcpPacket->header.p = 0; - rtcpPacket->header.pt = RTCP_SDES; - rtcpPacket->header.count = 1; - rtcpPacket->header.lenN = htons(wordLen-1); + rtcpPacket->header.version = RTP_VERSION; + rtcpPacket->header.p = 0; + rtcpPacket->header.pt = RTCP_SDES; + rtcpPacket->header.count = 1; + rtcpPacket->header.lenN = htons(wordLen-1); - rtcpPacket->body.sdes.srcN = htonl(mRtpSource.getSsrc()+1); - rtcpPacket->body.sdes.item[0].type = RTCP_SDES_CNAME; - rtcpPacket->body.sdes.item[0].len = cname.size(); - memcpy( rtcpPacket->body.sdes.item[0].data, cname.data(), cname.size() ); + rtcpPacket->body.sdes.srcN = htonl(mRtpSource.getSsrc()+1); + rtcpPacket->body.sdes.item[0].type = RTCP_SDES_CNAME; + rtcpPacket->body.sdes.item[0].len = cname.size(); + memcpy( rtcpPacket->body.sdes.item[0].data, cname.data(), cname.size() ); - return( wordLen*sizeof(uint32_t) ); + return( wordLen*sizeof(uint32_t) ); } int RtpCtrlThread::generateBye( const unsigned char *packet, ssize_t packetLen ) { - RtcpPacket *rtcpPacket = (RtcpPacket *)packet; + RtcpPacket *rtcpPacket = (RtcpPacket *)packet; - int byteLen = sizeof(rtcpPacket->header)+sizeof(rtcpPacket->body.bye)+sizeof(rtcpPacket->body.bye.srcN[0]); - int wordLen = ((byteLen-1)/sizeof(uint32_t))+1; + int byteLen = sizeof(rtcpPacket->header)+sizeof(rtcpPacket->body.bye)+sizeof(rtcpPacket->body.bye.srcN[0]); + int wordLen = ((byteLen-1)/sizeof(uint32_t))+1; - rtcpPacket->header.version = RTP_VERSION; - rtcpPacket->header.p = 0; - rtcpPacket->header.pt = RTCP_BYE; - rtcpPacket->header.count = 1; - rtcpPacket->header.lenN = htons(wordLen-1); + rtcpPacket->header.version = RTP_VERSION; + rtcpPacket->header.p = 0; + rtcpPacket->header.pt = RTCP_BYE; + rtcpPacket->header.count = 1; + rtcpPacket->header.lenN = htons(wordLen-1); - rtcpPacket->body.bye.srcN[0] = htonl(mRtpSource.getSsrc()); + rtcpPacket->body.bye.srcN[0] = htonl(mRtpSource.getSsrc()); - return( wordLen*sizeof(uint32_t) ); + return( wordLen*sizeof(uint32_t) ); } int RtpCtrlThread::recvPackets( unsigned char *buffer, ssize_t nBytes ) { - unsigned char *bufferPtr = buffer; + unsigned char *bufferPtr = buffer; - // u_int32 len; /* length of compound RTCP packet in words */ - // rtcp_t *r; /* RTCP header */ - // rtcp_t *end; /* end of compound RTCP packet */ + // u_int32 len; /* length of compound RTCP packet in words */ + // rtcp_t *r; /* RTCP header */ + // rtcp_t *end; /* end of compound RTCP packet */ - // if ((*(u_int16 *)r & RTCP_VALID_MASK) != RTCP_VALID_VALUE) { - // /* something wrong with packet format */ - // } - // end = (rtcp_t *)((u_int32 *)r + len); + // if ((*(u_int16 *)r & RTCP_VALID_MASK) != RTCP_VALID_VALUE) { + // /* something wrong with packet format */ + // } + // end = (rtcp_t *)((u_int32 *)r + len); - // do r = (rtcp_t *)((u_int32 *)r + r->common.length + 1); - // while (r < end && r->common.version == 2); + // do r = (rtcp_t *)((u_int32 *)r + r->common.length + 1); + // while (r < end && r->common.version == 2); - // if (r != end) { - // /* something wrong with packet format */ - // } + // if (r != end) { + // /* something wrong with packet format */ + // } - while ( nBytes > 0 ) - { - int consumed = recvPacket( bufferPtr, nBytes ); - if ( consumed <= 0 ) - break; - bufferPtr += consumed; - nBytes -= consumed; - } - return( nBytes ); + while ( nBytes > 0 ) + { + int consumed = recvPacket( bufferPtr, nBytes ); + if ( consumed <= 0 ) + break; + bufferPtr += consumed; + nBytes -= consumed; + } + return( nBytes ); } int RtpCtrlThread::run() { - Debug( 2, "Starting control thread %x on port %d", mRtpSource.getSsrc(), mRtpSource.getLocalCtrlPort() ); - SockAddrInet localAddr, remoteAddr; + Debug( 2, "Starting control thread %x on port %d", mRtpSource.getSsrc(), mRtpSource.getLocalCtrlPort() ); + SockAddrInet localAddr, remoteAddr; - bool sendReports; - UdpInetSocket rtpCtrlServer; - if ( mRtpSource.getLocalHost() != "" ) + bool sendReports; + UdpInetSocket rtpCtrlServer; + if ( mRtpSource.getLocalHost() != "" ) + { + localAddr.resolve( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort(), "udp" ); + if ( !rtpCtrlServer.bind( localAddr ) ) + Fatal( "Failed to bind RTCP server" ); + sendReports = false; + Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() ); + } + else + { + localAddr.resolve( mRtpSource.getLocalCtrlPort(), "udp" ); + if ( !rtpCtrlServer.bind( localAddr ) ) + Fatal( "Failed to bind RTCP server" ); + Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() ); + remoteAddr.resolve( mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort(), "udp" ); + if ( !rtpCtrlServer.connect( remoteAddr ) ) + Fatal( "Failed to connect RTCP server" ); + Debug( 3, "Connected to %s:%d", mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort() ); + sendReports = true; + } + + // The only reason I can think of why we would have a timeout period is so that we can regularly send RR packets. + // Why 10 seconds? If anything I think this should be whatever timeout value was given in the DESCRIBE response + Select select( 10 ); + select.addReader( &rtpCtrlServer ); + + unsigned char buffer[ZM_NETWORK_BUFSIZ]; + + time_t last_receive = time(NULL); + bool timeout = false; // used as a flag that we had a timeout, and then sent an RR to see if we wake back up. Real timeout will happen when this is true. + + while ( !mStop && select.wait() >= 0 ) { + + time_t now = time(NULL); + Select::CommsList readable = select.getReadable(); + if ( readable.size() == 0 ) { - localAddr.resolve( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort(), "udp" ); - if ( !rtpCtrlServer.bind( localAddr ) ) - Fatal( "Failed to bind RTCP server" ); - sendReports = false; - Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() ); + if ( ! timeout ) { + // With this code here, we will send an SDES and RR packet every 10 seconds + ssize_t nBytes; + unsigned char *bufferPtr = buffer; + bufferPtr += generateRr( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); + bufferPtr += generateSdes( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); + Debug( 3, "Preventing timeout by sending %zd bytes on sd %d. Time since last receive: %d", bufferPtr-buffer, rtpCtrlServer.getWriteDesc(), ( now-last_receive) ); + if ( (nBytes = rtpCtrlServer.send( buffer, bufferPtr-buffer )) < 0 ) + Error( "Unable to send: %s", strerror( errno ) ); + timeout = true; + continue; + } else { + //Error( "RTCP timed out" ); + Debug(1, "RTCP timed out. Time since last receive: %d", ( now-last_receive) ); + continue; + //break; + } + } else { + timeout = false; + last_receive = time(NULL); } - else + for ( Select::CommsList::iterator iter = readable.begin(); iter != readable.end(); iter++ ) { - localAddr.resolve( mRtpSource.getLocalCtrlPort(), "udp" ); - if ( !rtpCtrlServer.bind( localAddr ) ) - Fatal( "Failed to bind RTCP server" ); - Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalCtrlPort() ); - remoteAddr.resolve( mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort(), "udp" ); - if ( !rtpCtrlServer.connect( remoteAddr ) ) - Fatal( "Failed to connect RTCP server" ); - Debug( 3, "Connected to %s:%d", mRtpSource.getRemoteHost().c_str(), mRtpSource.getRemoteCtrlPort() ); - sendReports = true; - } + if ( UdpInetSocket *socket = dynamic_cast(*iter) ) + { + ssize_t nBytes = socket->recv( buffer, sizeof(buffer) ); + Debug( 4, "Read %zd bytes on sd %d", nBytes, socket->getReadDesc() ); - // The only reason I can think of why we would have a timeout period is so that we can regularly send RR packets. - // Why 10 seconds? If anything I think this should be whatever timeout value was given in the DESCRIBE response - Select select( 10 ); - select.addReader( &rtpCtrlServer ); - - unsigned char buffer[ZM_NETWORK_BUFSIZ]; - - time_t last_receive = time(NULL); - bool timeout = false; // used as a flag that we had a timeout, and then sent an RR to see if we wake back up. Real timeout will happen when this is true. - - while ( !mStop && select.wait() >= 0 ) { - - time_t now = time(NULL); - Select::CommsList readable = select.getReadable(); - if ( readable.size() == 0 ) + if ( nBytes ) { - if ( ! timeout ) { - // With this code here, we will send an SDES and RR packet every 10 seconds - ssize_t nBytes; - unsigned char *bufferPtr = buffer; - bufferPtr += generateRr( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); - bufferPtr += generateSdes( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); - Debug( 3, "Preventing timeout by sending %zd bytes on sd %d. Time since last receive: %d", bufferPtr-buffer, rtpCtrlServer.getWriteDesc(), ( now-last_receive) ); - if ( (nBytes = rtpCtrlServer.send( buffer, bufferPtr-buffer )) < 0 ) - Error( "Unable to send: %s", strerror( errno ) ); - timeout = true; - continue; - } else { - //Error( "RTCP timed out" ); - Debug(1, "RTCP timed out. Time since last receive: %d", ( now-last_receive) ); - continue; - //break; - } - } else { - timeout = false; - last_receive = time(NULL); - } - for ( Select::CommsList::iterator iter = readable.begin(); iter != readable.end(); iter++ ) - { - if ( UdpInetSocket *socket = dynamic_cast(*iter) ) - { - ssize_t nBytes = socket->recv( buffer, sizeof(buffer) ); - Debug( 4, "Read %zd bytes on sd %d", nBytes, socket->getReadDesc() ); + recvPackets( buffer, nBytes ); - if ( nBytes ) - { - recvPackets( buffer, nBytes ); - - if ( sendReports ) - { - unsigned char *bufferPtr = buffer; - bufferPtr += generateRr( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); - bufferPtr += generateSdes( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); - Debug( 3, "Sending %zd bytes on sd %d", bufferPtr-buffer, rtpCtrlServer.getWriteDesc() ); - if ( (nBytes = rtpCtrlServer.send( buffer, bufferPtr-buffer )) < 0 ) - Error( "Unable to send: %s", strerror( errno ) ); - //Debug( 4, "Sent %d bytes on sd %d", nBytes, rtpCtrlServer.getWriteDesc() ); - } - } else { - // Here is another case of not receiving some data causing us to terminate... why? Sometimes there are pauses in the interwebs. - mStop = true; - break; - } - } - else - { - Panic( "Barfed" ); - } + if ( sendReports ) + { + unsigned char *bufferPtr = buffer; + bufferPtr += generateRr( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); + bufferPtr += generateSdes( bufferPtr, sizeof(buffer)-(bufferPtr-buffer) ); + Debug( 3, "Sending %zd bytes on sd %d", bufferPtr-buffer, rtpCtrlServer.getWriteDesc() ); + if ( (nBytes = rtpCtrlServer.send( buffer, bufferPtr-buffer )) < 0 ) + Error( "Unable to send: %s", strerror( errno ) ); + //Debug( 4, "Sent %d bytes on sd %d", nBytes, rtpCtrlServer.getWriteDesc() ); + } + } else { + // Here is another case of not receiving some data causing us to terminate... why? Sometimes there are pauses in the interwebs. + mStop = true; + break; } + } + else + { + Panic( "Barfed" ); + } } - rtpCtrlServer.close(); - mRtspThread.stop(); - return( 0 ); + } + rtpCtrlServer.close(); + mRtspThread.stop(); + return( 0 ); } #endif // HAVE_LIBAVFORMAT diff --git a/src/zm_rtp_ctrl.h b/src/zm_rtp_ctrl.h index 9b44b752b..2526f22ce 100644 --- a/src/zm_rtp_ctrl.h +++ b/src/zm_rtp_ctrl.h @@ -25,7 +25,7 @@ #include "zm_thread.h" // Defined in ffmpeg rtp.h -//#define RTP_MAX_SDES 255 // maximum text length for SDES +//#define RTP_MAX_SDES 255 // maximum text length for SDES // Big-endian mask for version, padding bit and packet type pair #define RTCP_VALID_MASK (0xc000 | 0x2000 | 0xfe) @@ -39,119 +39,119 @@ class RtpCtrlThread : public Thread friend class RtspThread; private: - typedef enum + typedef enum + { + RTCP_SR = 200, + RTCP_RR = 201, + RTCP_SDES = 202, + RTCP_BYE = 203, + RTCP_APP = 204 + } RtcpType; + + typedef enum + { + RTCP_SDES_END = 0, + RTCP_SDES_CNAME = 1, + RTCP_SDES_NAME = 2, + RTCP_SDES_EMAIL = 3, + RTCP_SDES_PHONE = 4, + RTCP_SDES_LOC = 5, + RTCP_SDES_TOOL = 6, + RTCP_SDES_NOTE = 7, + RTCP_SDES_PRIV = 8 + } RtcpSdesType; + + struct RtcpCommonHeader + { + uint8_t count:5; // varies by packet type + uint8_t p:1; // padding flag + uint8_t version:2; // protocol version + uint8_t pt; // RTCP packet type + uint16_t lenN; // pkt len in words, w/o this word, network order + }; + + // Reception report block + struct RtcpRr + { + uint32_t ssrcN; // data source being reported + int32_t lost:24; // cumul. no. pkts lost (signed!) + uint32_t fraction:8; // fraction lost since last SR/RR + uint32_t lastSeqN; // extended last seq. no. received, network order + uint32_t jitterN; // interarrival jitter, network order + uint32_t lsrN; // last SR packet from this source, network order + uint32_t dlsrN; // delay since last SR packet, network order + }; + + // SDES item + struct RtcpSdesItem + { + uint8_t type; // type of item (rtcp_sdes_type_t) + uint8_t len; // length of item (in octets) + char data[]; // text, not null-terminated + }; + + // RTCP packet + struct RtcpPacket + { + RtcpCommonHeader header; // common header + union { - RTCP_SR = 200, - RTCP_RR = 201, - RTCP_SDES = 202, - RTCP_BYE = 203, - RTCP_APP = 204 - } RtcpType; + // Sender Report (SR) + struct Sr + { + uint32_t ssrcN; // sender generating this report, network order + uint32_t ntpSecN; // NTP timestamp, network order + uint32_t ntpFracN; + uint32_t rtpTsN; // RTP timestamp, network order + uint32_t pSentN; // packets sent, network order + uint32_t oSentN; // octets sent, network order + RtcpRr rr[]; // variable-length list + } sr; - typedef enum - { - RTCP_SDES_END = 0, - RTCP_SDES_CNAME = 1, - RTCP_SDES_NAME = 2, - RTCP_SDES_EMAIL = 3, - RTCP_SDES_PHONE = 4, - RTCP_SDES_LOC = 5, - RTCP_SDES_TOOL = 6, - RTCP_SDES_NOTE = 7, - RTCP_SDES_PRIV = 8 - } RtcpSdesType; + // Reception Report (RR) + struct Rr + { + uint32_t ssrcN; // receiver generating this report + RtcpRr rr[]; // variable-length list + } rr; - struct RtcpCommonHeader - { - uint8_t count:5; // varies by packet type - uint8_t p:1; // padding flag - uint8_t version:2; // protocol version - uint8_t pt; // RTCP packet type - uint16_t lenN; // pkt len in words, w/o this word, network order - }; + // source description (SDES) + struct Sdes + { + uint32_t srcN; // first SSRC/CSRC + RtcpSdesItem item[]; // list of SDES items + } sdes; - // Reception report block - struct RtcpRr - { - uint32_t ssrcN; // data source being reported - int32_t lost:24; // cumul. no. pkts lost (signed!) - uint32_t fraction:8; // fraction lost since last SR/RR - uint32_t lastSeqN; // extended last seq. no. received, network order - uint32_t jitterN; // interarrival jitter, network order - uint32_t lsrN; // last SR packet from this source, network order - uint32_t dlsrN; // delay since last SR packet, network order - }; - - // SDES item - struct RtcpSdesItem - { - uint8_t type; // type of item (rtcp_sdes_type_t) - uint8_t len; // length of item (in octets) - char data[]; // text, not null-terminated - }; - - // RTCP packet - struct RtcpPacket - { - RtcpCommonHeader header; // common header - union - { - // Sender Report (SR) - struct Sr - { - uint32_t ssrcN; // sender generating this report, network order - uint32_t ntpSecN; // NTP timestamp, network order - uint32_t ntpFracN; - uint32_t rtpTsN; // RTP timestamp, network order - uint32_t pSentN; // packets sent, network order - uint32_t oSentN; // octets sent, network order - RtcpRr rr[]; // variable-length list - } sr; - - // Reception Report (RR) - struct Rr - { - uint32_t ssrcN; // receiver generating this report - RtcpRr rr[]; // variable-length list - } rr; - - // source description (SDES) - struct Sdes - { - uint32_t srcN; // first SSRC/CSRC - RtcpSdesItem item[]; // list of SDES items - } sdes; - - // BYE - struct Bye - { - uint32_t srcN[]; // list of sources - // can't express trailing text for reason (what does this mean? it's not even english!) - } bye; - } body; - }; + // BYE + struct Bye + { + uint32_t srcN[]; // list of sources + // can't express trailing text for reason (what does this mean? it's not even english!) + } bye; + } body; + }; private: - RtspThread &mRtspThread; - RtpSource &mRtpSource; - int mPort; - bool mStop; + RtspThread &mRtspThread; + RtpSource &mRtpSource; + int mPort; + bool mStop; private: - int recvPacket( const unsigned char *packet, ssize_t packetLen ); - int generateRr( const unsigned char *packet, ssize_t packetLen ); - int generateSdes( const unsigned char *packet, ssize_t packetLen ); - int generateBye( const unsigned char *packet, ssize_t packetLen ); - int recvPackets( unsigned char *buffer, ssize_t nBytes ); - int run(); + int recvPacket( const unsigned char *packet, ssize_t packetLen ); + int generateRr( const unsigned char *packet, ssize_t packetLen ); + int generateSdes( const unsigned char *packet, ssize_t packetLen ); + int generateBye( const unsigned char *packet, ssize_t packetLen ); + int recvPackets( unsigned char *buffer, ssize_t nBytes ); + int run(); public: - RtpCtrlThread( RtspThread &rtspThread, RtpSource &rtpSource ); + RtpCtrlThread( RtspThread &rtspThread, RtpSource &rtpSource ); - void stop() - { - mStop = true; - } + void stop() + { + mStop = true; + } }; #endif // ZM_RTP_CTRL_H diff --git a/src/zm_rtp_data.cpp b/src/zm_rtp_data.cpp index 257f46947..687a4995e 100644 --- a/src/zm_rtp_data.cpp +++ b/src/zm_rtp_data.cpp @@ -33,88 +33,88 @@ RtpDataThread::RtpDataThread( RtspThread &rtspThread, RtpSource &rtpSource ) : m bool RtpDataThread::recvPacket( const unsigned char *packet, size_t packetLen ) { - const RtpDataHeader *rtpHeader; - rtpHeader = (RtpDataHeader *)packet; + const RtpDataHeader *rtpHeader; + rtpHeader = (RtpDataHeader *)packet; - //printf( "D: " ); - //for ( int i = 0; i < 32; i++ ) - //printf( "%02x ", (unsigned char)packet[i] ); - //printf( "\n" ); + //printf( "D: " ); + //for ( int i = 0; i < 32; i++ ) + //printf( "%02x ", (unsigned char)packet[i] ); + //printf( "\n" ); - Debug( 5, "Ver: %d", rtpHeader->version ); - Debug( 5, "P: %d", rtpHeader->p ); - Debug( 5, "Pt: %d", rtpHeader->pt ); - Debug( 5, "Mk: %d", rtpHeader->m ); - Debug( 5, "Seq: %d", ntohs(rtpHeader->seqN) ); - Debug( 5, "T/S: %x", ntohl(rtpHeader->timestampN) ); - Debug( 5, "SSRC: %x", ntohl(rtpHeader->ssrcN) ); + Debug( 5, "Ver: %d", rtpHeader->version ); + Debug( 5, "P: %d", rtpHeader->p ); + Debug( 5, "Pt: %d", rtpHeader->pt ); + Debug( 5, "Mk: %d", rtpHeader->m ); + Debug( 5, "Seq: %d", ntohs(rtpHeader->seqN) ); + Debug( 5, "T/S: %x", ntohl(rtpHeader->timestampN) ); + Debug( 5, "SSRC: %x", ntohl(rtpHeader->ssrcN) ); - //unsigned short seq = ntohs(rtpHeader->seqN); - unsigned long ssrc = ntohl(rtpHeader->ssrcN); + //unsigned short seq = ntohs(rtpHeader->seqN); + unsigned long ssrc = ntohl(rtpHeader->ssrcN); - if ( mRtpSource.getSsrc() && (ssrc != mRtpSource.getSsrc()) ) - { - Warning( "Discarding packet for unrecognised ssrc %lx", ssrc ); - return( false ); - } + if ( mRtpSource.getSsrc() && (ssrc != mRtpSource.getSsrc()) ) + { + Warning( "Discarding packet for unrecognised ssrc %lx", ssrc ); + return( false ); + } - return( mRtpSource.handlePacket( packet, packetLen ) ); + return( mRtpSource.handlePacket( packet, packetLen ) ); } int RtpDataThread::run() { - Debug( 2, "Starting data thread %d on port %d", mRtpSource.getSsrc(), mRtpSource.getLocalDataPort() ); + Debug( 2, "Starting data thread %d on port %d", mRtpSource.getSsrc(), mRtpSource.getLocalDataPort() ); - SockAddrInet localAddr; - UdpInetServer rtpDataSocket; - if ( mRtpSource.getLocalHost() != "" ) - localAddr.resolve( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort(), "udp" ); - else - localAddr.resolve( mRtpSource.getLocalDataPort(), "udp" ); - if ( !rtpDataSocket.bind( localAddr ) ) - Fatal( "Failed to bind RTP server" ); - Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() ); + SockAddrInet localAddr; + UdpInetServer rtpDataSocket; + if ( mRtpSource.getLocalHost() != "" ) + localAddr.resolve( mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort(), "udp" ); + else + localAddr.resolve( mRtpSource.getLocalDataPort(), "udp" ); + if ( !rtpDataSocket.bind( localAddr ) ) + Fatal( "Failed to bind RTP server" ); + Debug( 3, "Bound to %s:%d", mRtpSource.getLocalHost().c_str(), mRtpSource.getLocalDataPort() ); - Select select( 3 ); - select.addReader( &rtpDataSocket ); + Select select( 3 ); + select.addReader( &rtpDataSocket ); - unsigned char buffer[ZM_NETWORK_BUFSIZ]; - while ( !mStop && select.wait() >= 0 ) - { - if ( mStop ) - break; - Select::CommsList readable = select.getReadable(); - if ( readable.size() == 0 ) + unsigned char buffer[ZM_NETWORK_BUFSIZ]; + while ( !mStop && select.wait() >= 0 ) + { + if ( mStop ) + break; + Select::CommsList readable = select.getReadable(); + if ( readable.size() == 0 ) + { + Error( "RTP timed out" ); + mStop = true; + break; + } + for ( Select::CommsList::iterator iter = readable.begin(); iter != readable.end(); iter++ ) + { + if ( UdpInetServer *socket = dynamic_cast(*iter) ) + { + int nBytes = socket->recv( buffer, sizeof(buffer) ); + Debug( 4, "Got %d bytes on sd %d", nBytes, socket->getReadDesc() ); + if ( nBytes ) { - Error( "RTP timed out" ); - mStop = true; - break; + recvPacket( buffer, nBytes ); } - for ( Select::CommsList::iterator iter = readable.begin(); iter != readable.end(); iter++ ) + else { - if ( UdpInetServer *socket = dynamic_cast(*iter) ) - { - int nBytes = socket->recv( buffer, sizeof(buffer) ); - Debug( 4, "Got %d bytes on sd %d", nBytes, socket->getReadDesc() ); - if ( nBytes ) - { - recvPacket( buffer, nBytes ); - } - else - { - mStop = true; - break; - } - } - else - { - Panic( "Barfed" ); - } + mStop = true; + break; } - } - rtpDataSocket.close(); - mRtspThread.stop(); - return( 0 ); + } + else + { + Panic( "Barfed" ); + } + } + } + rtpDataSocket.close(); + mRtspThread.stop(); + return( 0 ); } #endif // HAVE_LIBAVFORMAT diff --git a/src/zm_rtp_data.h b/src/zm_rtp_data.h index 6c957a3ad..378c5e2e6 100644 --- a/src/zm_rtp_data.h +++ b/src/zm_rtp_data.h @@ -30,16 +30,16 @@ class RtpSource; struct RtpDataHeader { - uint8_t cc:4; // CSRC count - uint8_t x:1; // header extension flag - uint8_t p:1; // padding flag - uint8_t version:2; // protocol version - uint8_t pt:7; // payload type - uint8_t m:1; // marker bit - uint16_t seqN; // sequence number, network order - uint32_t timestampN; // timestamp, network order - uint32_t ssrcN; // synchronization source, network order - uint32_t csrc[]; // optional CSRC list + uint8_t cc:4; // CSRC count + uint8_t x:1; // header extension flag + uint8_t p:1; // padding flag + uint8_t version:2; // protocol version + uint8_t pt:7; // payload type + uint8_t m:1; // marker bit + uint16_t seqN; // sequence number, network order + uint32_t timestampN; // timestamp, network order + uint32_t ssrcN; // synchronization source, network order + uint32_t csrc[]; // optional CSRC list }; class RtpDataThread : public Thread @@ -47,21 +47,21 @@ class RtpDataThread : public Thread friend class RtspThread; private: - RtspThread &mRtspThread; - RtpSource &mRtpSource; - bool mStop; + RtspThread &mRtspThread; + RtpSource &mRtpSource; + bool mStop; private: - bool recvPacket( const unsigned char *packet, size_t packetLen ); - int run(); + bool recvPacket( const unsigned char *packet, size_t packetLen ); + int run(); public: - RtpDataThread( RtspThread &rtspThread, RtpSource &rtpSource ); + RtpDataThread( RtspThread &rtspThread, RtpSource &rtpSource ); - void stop() - { - mStop = true; - } + void stop() + { + mStop = true; + } }; #endif // ZM_RTP_DATA_H diff --git a/src/zm_rtp_source.h b/src/zm_rtp_source.h index cd41424ac..b86577e01 100644 --- a/src/zm_rtp_source.h +++ b/src/zm_rtp_source.h @@ -35,152 +35,152 @@ struct RtpDataHeader; class RtpSource { public: - typedef enum { EMPTY, FILLING, READY } FrameState; + typedef enum { EMPTY, FILLING, READY } FrameState; private: - static const int RTP_SEQ_MOD = 1<<16; - static const int MAX_DROPOUT = 3000; - static const int MAX_MISORDER = 100; - static const int MIN_SEQUENTIAL = 2; + static const int RTP_SEQ_MOD = 1<<16; + static const int MAX_DROPOUT = 3000; + static const int MAX_MISORDER = 100; + static const int MIN_SEQUENTIAL = 2; private: - // Identity - int mId; // General id (usually monitor id) - std::string mCname; // Canonical name, for SDES + // Identity + int mId; // General id (usually monitor id) + std::string mCname; // Canonical name, for SDES - // RTP/RTCP fields - uint32_t mSsrc; - uint16_t mMaxSeq; // highest seq. number seen - uint32_t mCycles; // shifted count of seq. number cycles - uint32_t mBaseSeq; // base seq number - uint32_t mBadSeq; // last 'bad' seq number + 1 - uint32_t mProbation; // sequ. packets till source is valid - uint32_t mReceivedPackets; // packets received - uint32_t mExpectedPrior; // packet expected at last interval - uint32_t mReceivedPrior; // packet received at last interval - uint32_t mTransit; // relative trans time for prev pkt - uint32_t mJitter; // estimated jitter - - // Ports/Channels - std::string mLocalHost; - int mLocalPortChans[2]; - std::string mRemoteHost; - int mRemotePortChans[2]; + // RTP/RTCP fields + uint32_t mSsrc; + uint16_t mMaxSeq; // highest seq. number seen + uint32_t mCycles; // shifted count of seq. number cycles + uint32_t mBaseSeq; // base seq number + uint32_t mBadSeq; // last 'bad' seq number + 1 + uint32_t mProbation; // sequ. packets till source is valid + uint32_t mReceivedPackets; // packets received + uint32_t mExpectedPrior; // packet expected at last interval + uint32_t mReceivedPrior; // packet received at last interval + uint32_t mTransit; // relative trans time for prev pkt + uint32_t mJitter; // estimated jitter + + // Ports/Channels + std::string mLocalHost; + int mLocalPortChans[2]; + std::string mRemoteHost; + int mRemotePortChans[2]; - // Time keys - uint32_t mRtpClock; - uint32_t mRtpFactor; - struct timeval mBaseTimeReal; - struct timeval mBaseTimeNtp; - uint32_t mBaseTimeRtp; + // Time keys + uint32_t mRtpClock; + uint32_t mRtpFactor; + struct timeval mBaseTimeReal; + struct timeval mBaseTimeNtp; + uint32_t mBaseTimeRtp; - struct timeval mLastSrTimeReal; - uint32_t mLastSrTimeNtpSecs; - uint32_t mLastSrTimeNtpFrac; - struct timeval mLastSrTimeNtp; - uint32_t mLastSrTimeRtp; + struct timeval mLastSrTimeReal; + uint32_t mLastSrTimeNtpSecs; + uint32_t mLastSrTimeNtpFrac; + struct timeval mLastSrTimeNtp; + uint32_t mLastSrTimeRtp; - // Stats, intermittently updated - uint32_t mExpectedPackets; - uint32_t mLostPackets; - uint8_t mLostFraction; + // Stats, intermittently updated + uint32_t mExpectedPackets; + uint32_t mLostPackets; + uint8_t mLostFraction; - _AVCODECID mCodecId; + _AVCODECID mCodecId; - Buffer mFrame; - int mFrameCount; - bool mFrameGood; - bool prevM; - ThreadData mFrameReady; - ThreadData mFrameProcessed; + Buffer mFrame; + int mFrameCount; + bool mFrameGood; + bool prevM; + ThreadData mFrameReady; + ThreadData mFrameProcessed; private: - void init( uint16_t seq ); + void init( uint16_t seq ); public: - RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime, _AVCODECID codecId ); - - bool updateSeq( uint16_t seq ); - void updateJitter( const RtpDataHeader *header ); - void updateRtcpData( uint32_t ntpTimeSecs, uint32_t ntpTimeFrac, uint32_t rtpTime ); - void updateRtcpStats(); + RtpSource( int id, const std::string &localHost, int localPortBase, const std::string &remoteHost, int remotePortBase, uint32_t ssrc, uint16_t seq, uint32_t rtpClock, uint32_t rtpTime, _AVCODECID codecId ); + + bool updateSeq( uint16_t seq ); + void updateJitter( const RtpDataHeader *header ); + void updateRtcpData( uint32_t ntpTimeSecs, uint32_t ntpTimeFrac, uint32_t rtpTime ); + void updateRtcpStats(); - bool handlePacket( const unsigned char *packet, size_t packetLen ); + bool handlePacket( const unsigned char *packet, size_t packetLen ); - uint32_t getSsrc() const - { - return( mSsrc ); - } - void setSsrc( uint32_t ssrc ) - { - mSsrc = ssrc; - } + uint32_t getSsrc() const + { + return( mSsrc ); + } + void setSsrc( uint32_t ssrc ) + { + mSsrc = ssrc; + } - bool getFrame( Buffer &buffer ); + bool getFrame( Buffer &buffer ); - const std::string &getCname() const - { - return( mCname ); - } + const std::string &getCname() const + { + return( mCname ); + } - const std::string &getLocalHost() const - { - return( mLocalHost ); - } + const std::string &getLocalHost() const + { + return( mLocalHost ); + } - int getLocalDataPort() const - { - return( mLocalPortChans[0] ); - } + int getLocalDataPort() const + { + return( mLocalPortChans[0] ); + } - int getLocalCtrlPort() const - { - return( mLocalPortChans[1] ); - } + int getLocalCtrlPort() const + { + return( mLocalPortChans[1] ); + } - const std::string &getRemoteHost() const - { - return( mRemoteHost ); - } + const std::string &getRemoteHost() const + { + return( mRemoteHost ); + } - int getRemoteDataPort() const - { - return( mRemotePortChans[0] ); - } + int getRemoteDataPort() const + { + return( mRemotePortChans[0] ); + } - int getRemoteCtrlPort() const - { - return( mRemotePortChans[1] ); - } + int getRemoteCtrlPort() const + { + return( mRemotePortChans[1] ); + } - uint32_t getMaxSeq() const - { - return( mCycles + mMaxSeq ); - } + uint32_t getMaxSeq() const + { + return( mCycles + mMaxSeq ); + } - uint32_t getExpectedPackets() const - { - return( mExpectedPackets ); - } - - uint32_t getLostPackets() const - { - return( mLostPackets ); - } + uint32_t getExpectedPackets() const + { + return( mExpectedPackets ); + } + + uint32_t getLostPackets() const + { + return( mLostPackets ); + } - uint8_t getLostFraction() const - { - return( mLostFraction ); - } + uint8_t getLostFraction() const + { + return( mLostFraction ); + } - uint32_t getJitter() const - { - return( mJitter >> 4 ); - } + uint32_t getJitter() const + { + return( mJitter >> 4 ); + } - uint32_t getLastSrTimestamp() const - { - return( ((mLastSrTimeNtpSecs&0xffff)<<16)|(mLastSrTimeNtpFrac>>16) ); - } + uint32_t getLastSrTimestamp() const + { + return( ((mLastSrTimeNtpSecs&0xffff)<<16)|(mLastSrTimeNtpFrac>>16) ); + } }; #endif // HAVE_LIBAVCODEC diff --git a/src/zm_rtsp.cpp b/src/zm_rtsp.cpp index 7ac80e9b6..b248d1f05 100644 --- a/src/zm_rtsp.cpp +++ b/src/zm_rtsp.cpp @@ -38,860 +38,860 @@ RtspThread::PortSet RtspThread::smAssignedPorts; bool RtspThread::sendCommand( std::string message ) { - if ( mNeedAuth ) { - StringVector parts = split( message, " " ); - if (parts.size() > 1) - message += mAuthenticator->getAuthHeader(parts[0], parts[1]); - } - message += stringtf( "User-Agent: ZoneMinder/%s\r\n", ZM_VERSION ); - message += stringtf( "CSeq: %d\r\n\r\n", ++mSeq ); - Debug( 2, "Sending RTSP message: %s", message.c_str() ); - if ( mMethod == RTP_RTSP_HTTP ) + if ( mNeedAuth ) { + StringVector parts = split( message, " " ); + if (parts.size() > 1) + message += mAuthenticator->getAuthHeader(parts[0], parts[1]); + } + message += stringtf( "User-Agent: ZoneMinder/%s\r\n", ZM_VERSION ); + message += stringtf( "CSeq: %d\r\n\r\n", ++mSeq ); + Debug( 2, "Sending RTSP message: %s", message.c_str() ); + if ( mMethod == RTP_RTSP_HTTP ) + { + message = base64Encode( message ); + Debug( 2, "Sending encoded RTSP message: %s", message.c_str() ); + if ( mRtspSocket2.send( message.c_str(), message.size() ) != (int)message.length() ) { - message = base64Encode( message ); - Debug( 2, "Sending encoded RTSP message: %s", message.c_str() ); - if ( mRtspSocket2.send( message.c_str(), message.size() ) != (int)message.length() ) - { - Error( "Unable to send message '%s': %s", message.c_str(), strerror(errno) ); - return( false ); - } + Error( "Unable to send message '%s': %s", message.c_str(), strerror(errno) ); + return( false ); } - else + } + else + { + if ( mRtspSocket.send( message.c_str(), message.size() ) != (int)message.length() ) { - if ( mRtspSocket.send( message.c_str(), message.size() ) != (int)message.length() ) - { - Error( "Unable to send message '%s': %s", message.c_str(), strerror(errno) ); - return( false ); - } + Error( "Unable to send message '%s': %s", message.c_str(), strerror(errno) ); + return( false ); } - return( true ); + } + return( true ); } bool RtspThread::recvResponse( std::string &response ) { - if ( mRtspSocket.recv( response ) < 0 ) - Error( "Recv failed; %s", strerror(errno) ); - Debug( 2, "Received RTSP response: %s (%zd bytes)", response.c_str(), response.size() ); - float respVer = 0; - respCode = -1; - char respText[ZM_NETWORK_BUFSIZ]; - if ( sscanf( response.c_str(), "RTSP/%f %3d %[^\r\n]\r\n", &respVer, &respCode, respText ) != 3 ) + if ( mRtspSocket.recv( response ) < 0 ) + Error( "Recv failed; %s", strerror(errno) ); + Debug( 2, "Received RTSP response: %s (%zd bytes)", response.c_str(), response.size() ); + float respVer = 0; + respCode = -1; + char respText[ZM_NETWORK_BUFSIZ]; + if ( sscanf( response.c_str(), "RTSP/%f %3d %[^\r\n]\r\n", &respVer, &respCode, respText ) != 3 ) + { + if ( isalnum(response[0]) ) { - if ( isalnum(response[0]) ) - { - Error( "Response parse failure in '%s'", response.c_str() ); - } - else - { - Error( "Response parse failure, %zd bytes follow", response.size() ); - if ( response.size() ) - Hexdump( Logger::ERROR, response.data(), min(response.size(),16) ); - } - return( false ); + Error( "Response parse failure in '%s'", response.c_str() ); } - if ( respCode == 401) + else { - Debug( 2, "Got 401 access denied response code, check WWW-Authenticate header and retry"); - mAuthenticator->checkAuthResponse(response); - mNeedAuth = true; - return( false ); - } - else if ( respCode != 200 ) - { - Error( "Unexpected response code %d, text is '%s'", respCode, respText ); - return( false ); + Error( "Response parse failure, %zd bytes follow", response.size() ); + if ( response.size() ) + Hexdump( Logger::ERROR, response.data(), min(response.size(),16) ); } - return( true ); + return( false ); + } + if ( respCode == 401) + { + Debug( 2, "Got 401 access denied response code, check WWW-Authenticate header and retry"); + mAuthenticator->checkAuthResponse(response); + mNeedAuth = true; + return( false ); + } + else if ( respCode != 200 ) + { + Error( "Unexpected response code %d, text is '%s'", respCode, respText ); + return( false ); + } + return( true ); } int RtspThread::requestPorts() { - if ( !smMinDataPort ) + if ( !smMinDataPort ) + { + char sql[ZM_SQL_SML_BUFSIZ]; + strncpy( sql, "select Id from Monitors where Function != 'None' and Type = 'Remote' and Protocol = 'rtsp' and Method = 'rtpUni' order by Id asc", sizeof(sql) ); + if ( mysql_query( &dbconn, sql ) ) { - char sql[ZM_SQL_SML_BUFSIZ]; - strncpy( sql, "select Id from Monitors where Function != 'None' and Type = 'Remote' and Protocol = 'rtsp' and Method = 'rtpUni' order by Id asc", sizeof(sql) ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - MYSQL_RES *result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - int nMonitors = mysql_num_rows( result ); - int position = 0; - if ( nMonitors ) - { - for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) - { - int id = atoi(dbrow[0]); - if ( mId == id ) - { - position = i; - break; - } - } - } - else - { - // Minor hack for testing when not strictly enabled - nMonitors = 1; - position = 0; - } - mysql_free_result(result); - int portRange = int(((config.max_rtp_port-config.min_rtp_port)+1)/nMonitors); - smMinDataPort = config.min_rtp_port + (position * portRange); - smMaxDataPort = smMinDataPort + portRange - 1; - Debug( 2, "Assigned RTP port range is %d-%d", smMinDataPort, smMaxDataPort ); - } - for ( int i = smMinDataPort; i <= smMaxDataPort; i++ ) + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) { - PortSet::const_iterator iter = smAssignedPorts.find( i ); - if ( iter == smAssignedPorts.end() ) - { - smAssignedPorts.insert( i ); - return( i ); - } + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); } - Panic( "Can assign RTP port, no ports left in pool" ); - return( -1 ); + int nMonitors = mysql_num_rows( result ); + int position = 0; + if ( nMonitors ) + { + for( int i = 0; MYSQL_ROW dbrow = mysql_fetch_row( result ); i++ ) + { + int id = atoi(dbrow[0]); + if ( mId == id ) + { + position = i; + break; + } + } + } + else + { + // Minor hack for testing when not strictly enabled + nMonitors = 1; + position = 0; + } + mysql_free_result(result); + int portRange = int(((config.max_rtp_port-config.min_rtp_port)+1)/nMonitors); + smMinDataPort = config.min_rtp_port + (position * portRange); + smMaxDataPort = smMinDataPort + portRange - 1; + Debug( 2, "Assigned RTP port range is %d-%d", smMinDataPort, smMaxDataPort ); + } + for ( int i = smMinDataPort; i <= smMaxDataPort; i++ ) + { + PortSet::const_iterator iter = smAssignedPorts.find( i ); + if ( iter == smAssignedPorts.end() ) + { + smAssignedPorts.insert( i ); + return( i ); + } + } + Panic( "Can assign RTP port, no ports left in pool" ); + return( -1 ); } void RtspThread::releasePorts( int port ) { - if ( port > 0 ) - smAssignedPorts.erase( port ); + if ( port > 0 ) + smAssignedPorts.erase( port ); } RtspThread::RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth, bool rtsp_describe) : - mId( id ), - mMethod( method ), - mProtocol( protocol ), - mHost( host ), - mPort( port ), - mPath( path ), - mRtspDescribe( rtsp_describe ), - mSessDesc( 0 ), - mFormatContext( 0 ), - mSeq( 0 ), - mSession( 0 ), - mSsrc( 0 ), - mDist( UNDEFINED ), - mRtpTime( 0 ), - mStop( false ) + mId( id ), + mMethod( method ), + mProtocol( protocol ), + mHost( host ), + mPort( port ), + mPath( path ), + mRtspDescribe( rtsp_describe ), + mSessDesc( 0 ), + mFormatContext( 0 ), + mSeq( 0 ), + mSession( 0 ), + mSsrc( 0 ), + mDist( UNDEFINED ), + mRtpTime( 0 ), + mStop( false ) { - mUrl = mProtocol+"://"+mHost+":"+mPort; - if ( !mPath.empty() ) - { - if ( mPath[0] == '/' ) - mUrl += mPath; - else - mUrl += '/'+mPath; - } - - mSsrc = rand(); - - Debug( 2, "RTSP Local SSRC is %x", mSsrc ); - - if ( mMethod == RTP_RTSP_HTTP ) - mHttpSession = stringtf( "%d", rand() ); - - mNeedAuth = false; - StringVector parts = split(auth,":"); - if (parts.size() > 1) - mAuthenticator = new zm::Authenticator(parts[0], parts[1]); + mUrl = mProtocol+"://"+mHost+":"+mPort; + if ( !mPath.empty() ) + { + if ( mPath[0] == '/' ) + mUrl += mPath; else - mAuthenticator = new zm::Authenticator(parts[0], ""); + mUrl += '/'+mPath; + } + + mSsrc = rand(); + + Debug( 2, "RTSP Local SSRC is %x", mSsrc ); + + if ( mMethod == RTP_RTSP_HTTP ) + mHttpSession = stringtf( "%d", rand() ); + + mNeedAuth = false; + StringVector parts = split(auth,":"); + if (parts.size() > 1) + mAuthenticator = new zm::Authenticator(parts[0], parts[1]); + else + mAuthenticator = new zm::Authenticator(parts[0], ""); } RtspThread::~RtspThread() { - if ( mFormatContext ) - { + if ( mFormatContext ) + { #if LIBAVFORMAT_VERSION_CHECK(52, 96, 0, 96, 0) - avformat_free_context( mFormatContext ); + avformat_free_context( mFormatContext ); #else - av_free_format_context( mFormatContext ); + av_free_format_context( mFormatContext ); #endif - mFormatContext = NULL; - } - if ( mSessDesc ) - { - delete mSessDesc; - mSessDesc = NULL; - } - delete mAuthenticator; + mFormatContext = NULL; + } + if ( mSessDesc ) + { + delete mSessDesc; + mSessDesc = NULL; + } + delete mAuthenticator; } int RtspThread::run() { - std::string message; - std::string response; + std::string message; + std::string response; - response.reserve( ZM_NETWORK_BUFSIZ ); + response.reserve( ZM_NETWORK_BUFSIZ ); - if ( !mRtspSocket.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) ) - Fatal( "Unable to connect RTSP socket" ); + if ( !mRtspSocket.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) ) + Fatal( "Unable to connect RTSP socket" ); + //Select select( 0.25 ); + //select.addReader( &mRtspSocket ); + //while ( select.wait() ) + //{ + //mRtspSocket.recv( response ); + //Debug( 4, "Drained %d bytes from RTSP socket", response.size() ); + //} + + + bool authTried = false; + if ( mMethod == RTP_RTSP_HTTP ) + { + if ( !mRtspSocket2.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) ) + Fatal( "Unable to connect auxiliary RTSP/HTTP socket" ); //Select select( 0.25 ); - //select.addReader( &mRtspSocket ); + //select.addReader( &mRtspSocket2 ); //while ( select.wait() ) //{ - //mRtspSocket.recv( response ); - //Debug( 4, "Drained %d bytes from RTSP socket", response.size() ); + //mRtspSocket2.recv( response ); + //Debug( 4, "Drained %d bytes from HTTP socket", response.size() ); //} - - bool authTried = false; - if ( mMethod == RTP_RTSP_HTTP ) + //possibly retry sending the message for authentication + int respCode = -1; + char respText[256]; + do { + message = "GET "+mPath+" HTTP/1.0\r\n"; + message += "X-SessionCookie: "+mHttpSession+"\r\n"; + if ( mNeedAuth ) { + message += mAuthenticator->getAuthHeader("GET", mPath); + authTried = true; + } + message += "Accept: application/x-rtsp-tunnelled\r\n"; + message += "\r\n"; + Debug( 2, "Sending HTTP message: %s", message.c_str() ); + if ( mRtspSocket.send( message.c_str(), message.size() ) != (int)message.length() ) + { + Error( "Unable to send message '%s': %s", message.c_str(), strerror(errno) ); + return( -1 ); + } + if ( mRtspSocket.recv( response ) < 0 ) + { + Error( "Recv failed; %s", strerror(errno) ); + return( -1 ); + } + + Debug( 2, "Received HTTP response: %s (%zd bytes)", response.c_str(), response.size() ); + float respVer = 0; + respCode = -1; + if ( sscanf( response.c_str(), "HTTP/%f %3d %[^\r\n]\r\n", &respVer, &respCode, respText ) != 3 ) + { + if ( isalnum(response[0]) ) + { + Error( "Response parse failure in '%s'", response.c_str() ); + } + else + { + Error( "Response parse failure, %zd bytes follow", response.size() ); + if ( response.size() ) + Hexdump( Logger::ERROR, response.data(), min(response.size(),16) ); + } + return( -1 ); + } + // If Server requests authentication, check WWW-Authenticate header and fill required fields + // for requested authentication method + if (respCode == 401 && !authTried) { + mNeedAuth = true; + mAuthenticator->checkAuthResponse(response); + Debug(2, "Processed 401 response"); + mRtspSocket.close(); + if ( !mRtspSocket.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) ) + Fatal( "Unable to reconnect RTSP socket" ); + Debug(2, "connection should be reopened now"); + } + + } while (respCode == 401 && !authTried); + + if ( respCode != 200 ) { - if ( !mRtspSocket2.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) ) - Fatal( "Unable to connect auxiliary RTSP/HTTP socket" ); - //Select select( 0.25 ); - //select.addReader( &mRtspSocket2 ); - //while ( select.wait() ) - //{ - //mRtspSocket2.recv( response ); - //Debug( 4, "Drained %d bytes from HTTP socket", response.size() ); - //} - - //possibly retry sending the message for authentication - int respCode = -1; - char respText[256]; - do { - message = "GET "+mPath+" HTTP/1.0\r\n"; - message += "X-SessionCookie: "+mHttpSession+"\r\n"; - if ( mNeedAuth ) { - message += mAuthenticator->getAuthHeader("GET", mPath); - authTried = true; - } - message += "Accept: application/x-rtsp-tunnelled\r\n"; - message += "\r\n"; - Debug( 2, "Sending HTTP message: %s", message.c_str() ); - if ( mRtspSocket.send( message.c_str(), message.size() ) != (int)message.length() ) - { - Error( "Unable to send message '%s': %s", message.c_str(), strerror(errno) ); - return( -1 ); - } - if ( mRtspSocket.recv( response ) < 0 ) - { - Error( "Recv failed; %s", strerror(errno) ); - return( -1 ); - } - - Debug( 2, "Received HTTP response: %s (%zd bytes)", response.c_str(), response.size() ); - float respVer = 0; - respCode = -1; - if ( sscanf( response.c_str(), "HTTP/%f %3d %[^\r\n]\r\n", &respVer, &respCode, respText ) != 3 ) - { - if ( isalnum(response[0]) ) - { - Error( "Response parse failure in '%s'", response.c_str() ); - } - else - { - Error( "Response parse failure, %zd bytes follow", response.size() ); - if ( response.size() ) - Hexdump( Logger::ERROR, response.data(), min(response.size(),16) ); - } - return( -1 ); - } - // If Server requests authentication, check WWW-Authenticate header and fill required fields - // for requested authentication method - if (respCode == 401 && !authTried) { - mNeedAuth = true; - mAuthenticator->checkAuthResponse(response); - Debug(2, "Processed 401 response"); - mRtspSocket.close(); - if ( !mRtspSocket.connect( mHost.c_str(), strtol( mPort.c_str(), NULL, 10 ) ) ) - Fatal( "Unable to reconnect RTSP socket" ); - Debug(2, "connection should be reopened now"); - } - - } while (respCode == 401 && !authTried); - - if ( respCode != 200 ) - { - Error( "Unexpected response code %d, text is '%s'", respCode, respText ); - return( -1 ); - } - - message = "POST "+mPath+" HTTP/1.0\r\n"; - message += "X-SessionCookie: "+mHttpSession+"\r\n"; - if ( mNeedAuth ) - message += mAuthenticator->getAuthHeader("POST", mPath); - message += "Content-Length: 32767\r\n"; - message += "Content-Type: application/x-rtsp-tunnelled\r\n"; - message += "\r\n"; - Debug( 2, "Sending HTTP message: %s", message.c_str() ); - if ( mRtspSocket2.send( message.c_str(), message.size() ) != (int)message.length() ) - { - Error( "Unable to send message '%s': %s", message.c_str(), strerror(errno) ); - return( -1 ); - } + Error( "Unexpected response code %d, text is '%s'", respCode, respText ); + return( -1 ); } - std::string localHost = ""; - int localPorts[2] = { 0, 0 }; + message = "POST "+mPath+" HTTP/1.0\r\n"; + message += "X-SessionCookie: "+mHttpSession+"\r\n"; + if ( mNeedAuth ) + message += mAuthenticator->getAuthHeader("POST", mPath); + message += "Content-Length: 32767\r\n"; + message += "Content-Type: application/x-rtsp-tunnelled\r\n"; + message += "\r\n"; + Debug( 2, "Sending HTTP message: %s", message.c_str() ); + if ( mRtspSocket2.send( message.c_str(), message.size() ) != (int)message.length() ) + { + Error( "Unable to send message '%s': %s", message.c_str(), strerror(errno) ); + return( -1 ); + } + } - // Request supported RTSP commands by the server - message = "OPTIONS "+mUrl+" RTSP/1.0\r\n"; - if ( !sendCommand( message ) ) + std::string localHost = ""; + int localPorts[2] = { 0, 0 }; + + // Request supported RTSP commands by the server + message = "OPTIONS "+mUrl+" RTSP/1.0\r\n"; + if ( !sendCommand( message ) ) + return( -1 ); + + // A negative return here may indicate auth failure, but we will have setup the auth mechanisms so we need to retry. + if ( !recvResponse( response ) ) { + if ( mNeedAuth ) { + Debug( 2, "Resending OPTIONS due to possible auth requirement" ); + if ( !sendCommand( message ) ) return( -1 ); + if ( !recvResponse( response ) ) + return( -1 ); + } else { + return( -1 ); + } + } // end if failed response maybe due to auth - // A negative return here may indicate auth failure, but we will have setup the auth mechanisms so we need to retry. - if ( !recvResponse( response ) ) { - if ( mNeedAuth ) { - Debug( 2, "Resending OPTIONS due to possible auth requirement" ); - if ( !sendCommand( message ) ) - return( -1 ); - if ( !recvResponse( response ) ) - return( -1 ); - } else { - return( -1 ); - } - } // end if failed response maybe due to auth + char publicLine[256] = ""; + StringVector lines = split( response, "\r\n" ); + for ( size_t i = 0; i < lines.size(); i++ ) + sscanf( lines[i].c_str(), "Public: %[^\r\n]\r\n", publicLine ); - char publicLine[256] = ""; - StringVector lines = split( response, "\r\n" ); + // Check if the server supports the GET_PARAMETER command + // If yes, it is likely that the server will request this command as a keepalive message + bool sendKeepalive = false; + if ( publicLine[0] && strstr(publicLine, "GET_PARAMETER") ) + sendKeepalive = true; + + message = "DESCRIBE "+mUrl+" RTSP/1.0\r\n"; + bool res; + do { + if (mNeedAuth) + authTried = true; + sendCommand( message ); + sleep( 1 ); + res = recvResponse( response ); + if (!res && respCode==401) + mNeedAuth = true; + } while (!res && respCode==401 && !authTried); + + const std::string endOfHeaders = "\r\n\r\n"; + size_t sdpStart = response.find( endOfHeaders ); + if( sdpStart == std::string::npos ) + return( -1 ); + + if ( mRtspDescribe ) + { + std::string DescHeader = response.substr( 0,sdpStart ); + Debug( 1, "Processing DESCRIBE response header '%s'", DescHeader.c_str() ); + + lines = split( DescHeader, "\r\n" ); for ( size_t i = 0; i < lines.size(); i++ ) - sscanf( lines[i].c_str(), "Public: %[^\r\n]\r\n", publicLine ); + { + // If the device sends us a url value for Content-Base in the response header, we should use that instead + if ( ( lines[i].size() > 13 ) && ( lines[i].substr( 0, 13 ) == "Content-Base:" ) ) + { + mUrl = trimSpaces( lines[i].substr( 13 ) ); + Info("Received new Content-Base in DESCRIBE response header. Updated device Url to: '%s'", mUrl.c_str() ); + break; + } + } + } - // Check if the server supports the GET_PARAMETER command - // If yes, it is likely that the server will request this command as a keepalive message - bool sendKeepalive = false; - if ( publicLine[0] && strstr(publicLine, "GET_PARAMETER") ) - sendKeepalive = true; + sdpStart += endOfHeaders.length(); - message = "DESCRIBE "+mUrl+" RTSP/1.0\r\n"; - bool res; - do { - if (mNeedAuth) - authTried = true; - sendCommand( message ); - sleep( 1 ); - res = recvResponse( response ); - if (!res && respCode==401) - mNeedAuth = true; - } while (!res && respCode==401 && !authTried); + std::string sdp = response.substr( sdpStart ); + Debug( 1, "Processing SDP '%s'", sdp.c_str() ); - const std::string endOfHeaders = "\r\n\r\n"; - size_t sdpStart = response.find( endOfHeaders ); - if( sdpStart == std::string::npos ) - return( -1 ); - - if ( mRtspDescribe ) - { - std::string DescHeader = response.substr( 0,sdpStart ); - Debug( 1, "Processing DESCRIBE response header '%s'", DescHeader.c_str() ); - - lines = split( DescHeader, "\r\n" ); - for ( size_t i = 0; i < lines.size(); i++ ) - { - // If the device sends us a url value for Content-Base in the response header, we should use that instead - if ( ( lines[i].size() > 13 ) && ( lines[i].substr( 0, 13 ) == "Content-Base:" ) ) - { - mUrl = trimSpaces( lines[i].substr( 13 ) ); - Info("Received new Content-Base in DESCRIBE response header. Updated device Url to: '%s'", mUrl.c_str() ); - break; - } - } - } - - sdpStart += endOfHeaders.length(); - - std::string sdp = response.substr( sdpStart ); - Debug( 1, "Processing SDP '%s'", sdp.c_str() ); - - try - { - mSessDesc = new SessionDescriptor( mUrl, sdp ); - mFormatContext = mSessDesc->generateFormatContext(); - } - catch( const Exception &e ) - { - Error( e.getMessage().c_str() ); - return( -1 ); - } + try + { + mSessDesc = new SessionDescriptor( mUrl, sdp ); + mFormatContext = mSessDesc->generateFormatContext(); + } + catch( const Exception &e ) + { + Error( e.getMessage().c_str() ); + return( -1 ); + } #if 0 - // New method using ffmpeg native functions - std::string authUrl = mUrl; - if ( !mAuth.empty() ) - authUrl.insert( authUrl.find( "://" )+3, mAuth+"@" ); + // New method using ffmpeg native functions + std::string authUrl = mUrl; + if ( !mAuth.empty() ) + authUrl.insert( authUrl.find( "://" )+3, mAuth+"@" ); - if ( av_open_input_file( &mFormatContext, authUrl.c_str(), NULL, 0, NULL ) != 0 ) - { - Error( "Unable to open input '%s'", authUrl.c_str() ); - return( -1 ); - } + if ( av_open_input_file( &mFormatContext, authUrl.c_str(), NULL, 0, NULL ) != 0 ) + { + Error( "Unable to open input '%s'", authUrl.c_str() ); + return( -1 ); + } #endif - uint32_t rtpClock = 0; - std::string trackUrl = mUrl; - std::string controlUrl; - - _AVCODECID codecId; - - if ( mFormatContext->nb_streams >= 1 ) + uint32_t rtpClock = 0; + std::string trackUrl = mUrl; + std::string controlUrl; + + _AVCODECID codecId; + + if ( mFormatContext->nb_streams >= 1 ) + { + for ( unsigned int i = 0; i < mFormatContext->nb_streams; i++ ) { - for ( unsigned int i = 0; i < mFormatContext->nb_streams; i++ ) - { - SessionDescriptor::MediaDescriptor *mediaDesc = mSessDesc->getStream( i ); + SessionDescriptor::MediaDescriptor *mediaDesc = mSessDesc->getStream( i ); #if (LIBAVCODEC_VERSION_CHECK(52, 64, 0, 64, 0) || LIBAVUTIL_VERSION_CHECK(50, 14, 0, 14, 0)) - if ( mFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ) + if ( mFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ) #else - if ( mFormatContext->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO ) + if ( mFormatContext->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO ) #endif - { - // Check if control Url is absolute or relative - controlUrl = mediaDesc->getControlUrl(); - if (std::equal(trackUrl.begin(), trackUrl.end(), controlUrl.begin())) - { - trackUrl = controlUrl; - } - else - { - if ( *trackUrl.rbegin() != '/') { - trackUrl += "/" + controlUrl; - } else { - trackUrl += controlUrl; - } - } - rtpClock = mediaDesc->getClock(); - codecId = mFormatContext->streams[i]->codec->codec_id; - // Hackery pokery - //rtpClock = mFormatContext->streams[i]->codec->sample_rate; - break; - } + { + // Check if control Url is absolute or relative + controlUrl = mediaDesc->getControlUrl(); + if (std::equal(trackUrl.begin(), trackUrl.end(), controlUrl.begin())) + { + trackUrl = controlUrl; } + else + { + if ( *trackUrl.rbegin() != '/') { + trackUrl += "/" + controlUrl; + } else { + trackUrl += controlUrl; + } + } + rtpClock = mediaDesc->getClock(); + codecId = mFormatContext->streams[i]->codec->codec_id; + // Hackery pokery + //rtpClock = mFormatContext->streams[i]->codec->sample_rate; + break; + } } + } - switch( mMethod ) + switch( mMethod ) + { + case RTP_UNICAST : { - case RTP_UNICAST : - { - localPorts[0] = requestPorts(); - localPorts[1] = localPorts[0]+1; + localPorts[0] = requestPorts(); + localPorts[1] = localPorts[0]+1; - message = "SETUP "+trackUrl+" RTSP/1.0\r\nTransport: RTP/AVP;unicast;client_port="+stringtf( "%d", localPorts[0] )+"-"+stringtf( "%d", localPorts[1] )+"\r\n"; - break; - } - case RTP_MULTICAST : - { - message = "SETUP "+trackUrl+" RTSP/1.0\r\nTransport: RTP/AVP;multicast\r\n"; - break; - } - case RTP_RTSP : - case RTP_RTSP_HTTP : - { - message = "SETUP "+trackUrl+" RTSP/1.0\r\nTransport: RTP/AVP/TCP;unicast\r\n"; - break; - } - default: - { - Panic( "Got unexpected method %d", mMethod ); - break; - } + message = "SETUP "+trackUrl+" RTSP/1.0\r\nTransport: RTP/AVP;unicast;client_port="+stringtf( "%d", localPorts[0] )+"-"+stringtf( "%d", localPorts[1] )+"\r\n"; + break; } - - if ( !sendCommand( message ) ) - return( -1 ); - if ( !recvResponse( response ) ) - return( -1 ); - - lines = split( response, "\r\n" ); - std::string session; - int timeout = 0; - char transport[256] = ""; - - for ( size_t i = 0; i < lines.size(); i++ ) + case RTP_MULTICAST : { - if ( ( lines[i].size() > 8 ) && ( lines[i].substr( 0, 8 ) == "Session:" ) ) - { - StringVector sessionLine = split( lines[i].substr(9), ";" ); - session = trimSpaces( sessionLine[0] ); - if ( sessionLine.size() == 2 ) - sscanf( trimSpaces( sessionLine[1] ).c_str(), "timeout=%d", &timeout ); - } - sscanf( lines[i].c_str(), "Transport: %s", transport ); + message = "SETUP "+trackUrl+" RTSP/1.0\r\nTransport: RTP/AVP;multicast\r\n"; + break; } - - if ( session.empty() ) - Fatal( "Unable to get session identifier from response '%s'", response.c_str() ); - - Debug( 2, "Got RTSP session %s, timeout %d secs", session.c_str(), timeout ); - - if ( !transport[0] ) - Fatal( "Unable to get transport details from response '%s'", response.c_str() ); - - Debug( 2, "Got RTSP transport %s", transport ); - - std::string method = ""; - int remotePorts[2] = { 0, 0 }; - int remoteChannels[2] = { 0, 0 }; - std::string distribution = ""; - unsigned long ssrc = 0; - StringVector parts = split( transport, ";" ); - for ( size_t i = 0; i < parts.size(); i++ ) + case RTP_RTSP : + case RTP_RTSP_HTTP : { - if ( parts[i] == "unicast" || parts[i] == "multicast" ) - distribution = parts[i]; - else if ( startsWith( parts[i], "server_port=" ) ) - { - method = "RTP/UNICAST"; - StringVector subparts = split( parts[i], "=" ); - StringVector ports = split( subparts[1], "-" ); - remotePorts[0] = strtol( ports[0].c_str(), NULL, 10 ); - remotePorts[1] = strtol( ports[1].c_str(), NULL, 10 ); - } - else if ( startsWith( parts[i], "interleaved=" ) ) - { - method = "RTP/RTSP"; - StringVector subparts = split( parts[i], "=" ); - StringVector channels = split( subparts[1], "-" ); - remoteChannels[0] = strtol( channels[0].c_str(), NULL, 10 ); - remoteChannels[1] = strtol( channels[1].c_str(), NULL, 10 ); - } - else if ( startsWith( parts[i], "port=" ) ) - { - method = "RTP/MULTICAST"; - StringVector subparts = split( parts[i], "=" ); - StringVector ports = split( subparts[1], "-" ); - localPorts[0] = strtol( ports[0].c_str(), NULL, 10 ); - localPorts[1] = strtol( ports[1].c_str(), NULL, 10 ); - } - else if ( startsWith( parts[i], "destination=" ) ) - { - StringVector subparts = split( parts[i], "=" ); - localHost = subparts[1]; - } - else if ( startsWith( parts[i], "ssrc=" ) ) - { - StringVector subparts = split( parts[i], "=" ); - ssrc = strtoll( subparts[1].c_str(), NULL, 16 ); - } + message = "SETUP "+trackUrl+" RTSP/1.0\r\nTransport: RTP/AVP/TCP;unicast\r\n"; + break; } - - Debug( 2, "RTSP Method is %s", method.c_str() ); - Debug( 2, "RTSP Distribution is %s", distribution.c_str() ); - Debug( 2, "RTSP SSRC is %lx", ssrc ); - Debug( 2, "RTSP Local Host is %s", localHost.c_str() ); - Debug( 2, "RTSP Local Ports are %d/%d", localPorts[0], localPorts[1] ); - Debug( 2, "RTSP Remote Ports are %d/%d", remotePorts[0], remotePorts[1] ); - Debug( 2, "RTSP Remote Channels are %d/%d", remoteChannels[0], remoteChannels[1] ); - - message = "PLAY "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\nRange: npt=0.000-\r\n"; - if ( !sendCommand( message ) ) - return( -1 ); - if ( !recvResponse( response ) ) - return( -1 ); - - lines = split( response, "\r\n" ); - std::string rtpInfo; - for ( size_t i = 0; i < lines.size(); i++ ) + default: { - if ( ( lines[i].size() > 9 ) && ( lines[i].substr( 0, 9 ) == "RTP-Info:" ) ) - rtpInfo = trimSpaces( lines[i].substr( 9 ) ); - // Check for a timeout again. Some rtsp devices don't send a timeout until after the PLAY command is sent - if ( ( lines[i].size() > 8 ) && ( lines[i].substr( 0, 8 ) == "Session:" ) && ( timeout == 0 ) ) + Panic( "Got unexpected method %d", mMethod ); + break; + } + } + + if ( !sendCommand( message ) ) + return( -1 ); + if ( !recvResponse( response ) ) + return( -1 ); + + lines = split( response, "\r\n" ); + std::string session; + int timeout = 0; + char transport[256] = ""; + + for ( size_t i = 0; i < lines.size(); i++ ) + { + if ( ( lines[i].size() > 8 ) && ( lines[i].substr( 0, 8 ) == "Session:" ) ) + { + StringVector sessionLine = split( lines[i].substr(9), ";" ); + session = trimSpaces( sessionLine[0] ); + if ( sessionLine.size() == 2 ) + sscanf( trimSpaces( sessionLine[1] ).c_str(), "timeout=%d", &timeout ); + } + sscanf( lines[i].c_str(), "Transport: %s", transport ); + } + + if ( session.empty() ) + Fatal( "Unable to get session identifier from response '%s'", response.c_str() ); + + Debug( 2, "Got RTSP session %s, timeout %d secs", session.c_str(), timeout ); + + if ( !transport[0] ) + Fatal( "Unable to get transport details from response '%s'", response.c_str() ); + + Debug( 2, "Got RTSP transport %s", transport ); + + std::string method = ""; + int remotePorts[2] = { 0, 0 }; + int remoteChannels[2] = { 0, 0 }; + std::string distribution = ""; + unsigned long ssrc = 0; + StringVector parts = split( transport, ";" ); + for ( size_t i = 0; i < parts.size(); i++ ) + { + if ( parts[i] == "unicast" || parts[i] == "multicast" ) + distribution = parts[i]; + else if ( startsWith( parts[i], "server_port=" ) ) + { + method = "RTP/UNICAST"; + StringVector subparts = split( parts[i], "=" ); + StringVector ports = split( subparts[1], "-" ); + remotePorts[0] = strtol( ports[0].c_str(), NULL, 10 ); + remotePorts[1] = strtol( ports[1].c_str(), NULL, 10 ); + } + else if ( startsWith( parts[i], "interleaved=" ) ) + { + method = "RTP/RTSP"; + StringVector subparts = split( parts[i], "=" ); + StringVector channels = split( subparts[1], "-" ); + remoteChannels[0] = strtol( channels[0].c_str(), NULL, 10 ); + remoteChannels[1] = strtol( channels[1].c_str(), NULL, 10 ); + } + else if ( startsWith( parts[i], "port=" ) ) + { + method = "RTP/MULTICAST"; + StringVector subparts = split( parts[i], "=" ); + StringVector ports = split( subparts[1], "-" ); + localPorts[0] = strtol( ports[0].c_str(), NULL, 10 ); + localPorts[1] = strtol( ports[1].c_str(), NULL, 10 ); + } + else if ( startsWith( parts[i], "destination=" ) ) + { + StringVector subparts = split( parts[i], "=" ); + localHost = subparts[1]; + } + else if ( startsWith( parts[i], "ssrc=" ) ) + { + StringVector subparts = split( parts[i], "=" ); + ssrc = strtoll( subparts[1].c_str(), NULL, 16 ); + } + } + + Debug( 2, "RTSP Method is %s", method.c_str() ); + Debug( 2, "RTSP Distribution is %s", distribution.c_str() ); + Debug( 2, "RTSP SSRC is %lx", ssrc ); + Debug( 2, "RTSP Local Host is %s", localHost.c_str() ); + Debug( 2, "RTSP Local Ports are %d/%d", localPorts[0], localPorts[1] ); + Debug( 2, "RTSP Remote Ports are %d/%d", remotePorts[0], remotePorts[1] ); + Debug( 2, "RTSP Remote Channels are %d/%d", remoteChannels[0], remoteChannels[1] ); + + message = "PLAY "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\nRange: npt=0.000-\r\n"; + if ( !sendCommand( message ) ) + return( -1 ); + if ( !recvResponse( response ) ) + return( -1 ); + + lines = split( response, "\r\n" ); + std::string rtpInfo; + for ( size_t i = 0; i < lines.size(); i++ ) + { + if ( ( lines[i].size() > 9 ) && ( lines[i].substr( 0, 9 ) == "RTP-Info:" ) ) + rtpInfo = trimSpaces( lines[i].substr( 9 ) ); + // Check for a timeout again. Some rtsp devices don't send a timeout until after the PLAY command is sent + if ( ( lines[i].size() > 8 ) && ( lines[i].substr( 0, 8 ) == "Session:" ) && ( timeout == 0 ) ) + { + StringVector sessionLine = split( lines[i].substr(9), ";" ); + if ( sessionLine.size() == 2 ) + sscanf( trimSpaces( sessionLine[1] ).c_str(), "timeout=%d", &timeout ); + if ( timeout > 0 ) + Debug( 2, "Got timeout %d secs from PLAY command response", timeout ); + } + } + + int seq = 0; + unsigned long rtpTime = 0; + StringVector streams; + if ( rtpInfo.empty() ) + { + Debug( 1, "RTP Info Empty. Starting values for Sequence and Rtptime shall be zero."); + } + else + { + Debug( 2, "Got RTP Info %s", rtpInfo.c_str() ); + // More than one stream can be included in the RTP Info + streams = split( rtpInfo.c_str(), "," ); + for ( size_t i = 0; i < streams.size(); i++ ) + { + // We want the stream that matches the trackUrl we are using + if ( streams[i].find(controlUrl.c_str()) != std::string::npos ) + { + // Parse the sequence and rtptime values + parts = split( streams[i].c_str(), ";" ); + for ( size_t j = 0; j < parts.size(); j++ ) { - StringVector sessionLine = split( lines[i].substr(9), ";" ); - if ( sessionLine.size() == 2 ) - sscanf( trimSpaces( sessionLine[1] ).c_str(), "timeout=%d", &timeout ); - if ( timeout > 0 ) - Debug( 2, "Got timeout %d secs from PLAY command response", timeout ); + if ( startsWith( parts[j], "seq=" ) ) + { + StringVector subparts = split( parts[j], "=" ); + seq = strtol( subparts[1].c_str(), NULL, 10 ); + } + else if ( startsWith( parts[j], "rtptime=" ) ) + { + StringVector subparts = split( parts[j], "=" ); + rtpTime = strtol( subparts[1].c_str(), NULL, 10 ); + } } + break; + } } + } - int seq = 0; - unsigned long rtpTime = 0; - StringVector streams; - if ( rtpInfo.empty() ) + Debug( 2, "RTSP Seq is %d", seq ); + Debug( 2, "RTSP Rtptime is %ld", rtpTime ); + + time_t lastKeepalive = time(NULL); + time_t now; + message = "GET_PARAMETER "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; + + switch( mMethod ) + { + case RTP_UNICAST : { - Debug( 1, "RTP Info Empty. Starting values for Sequence and Rtptime shall be zero."); - } - else - { - Debug( 2, "Got RTP Info %s", rtpInfo.c_str() ); - // More than one stream can be included in the RTP Info - streams = split( rtpInfo.c_str(), "," ); - for ( size_t i = 0; i < streams.size(); i++ ) - { - // We want the stream that matches the trackUrl we are using - if ( streams[i].find(controlUrl.c_str()) != std::string::npos ) - { - // Parse the sequence and rtptime values - parts = split( streams[i].c_str(), ";" ); - for ( size_t j = 0; j < parts.size(); j++ ) - { - if ( startsWith( parts[j], "seq=" ) ) - { - StringVector subparts = split( parts[j], "=" ); - seq = strtol( subparts[1].c_str(), NULL, 10 ); - } - else if ( startsWith( parts[j], "rtptime=" ) ) - { - StringVector subparts = split( parts[j], "=" ); - rtpTime = strtol( subparts[1].c_str(), NULL, 10 ); - } - } - break; - } - } - } + RtpSource *source = new RtpSource( mId, "", localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime, codecId ); + mSources[ssrc] = source; + RtpDataThread rtpDataThread( *this, *source ); + RtpCtrlThread rtpCtrlThread( *this, *source ); - Debug( 2, "RTSP Seq is %d", seq ); - Debug( 2, "RTSP Rtptime is %ld", rtpTime ); + rtpDataThread.start(); + rtpCtrlThread.start(); - time_t lastKeepalive = time(NULL); - time_t now; - message = "GET_PARAMETER "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; - - switch( mMethod ) - { - case RTP_UNICAST : - { - RtpSource *source = new RtpSource( mId, "", localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime, codecId ); - mSources[ssrc] = source; - RtpDataThread rtpDataThread( *this, *source ); - RtpCtrlThread rtpCtrlThread( *this, *source ); - - rtpDataThread.start(); - rtpCtrlThread.start(); - - while( !mStop ) - { - now = time(NULL); - // Send a keepalive message if the server supports this feature and we are close to the timeout expiration + while( !mStop ) + { + now = time(NULL); + // Send a keepalive message if the server supports this feature and we are close to the timeout expiration Debug(5, "sendkeepalive %d, timeout %d, now: %d last: %d since: %d", sendKeepalive, timeout, now, lastKeepalive, (now-lastKeepalive) ); - if ( sendKeepalive && (timeout > 0) && ((now-lastKeepalive) > (timeout-5)) ) - { - if ( !sendCommand( message ) ) - return( -1 ); - lastKeepalive = now; - } - usleep( 100000 ); - } + if ( sendKeepalive && (timeout > 0) && ((now-lastKeepalive) > (timeout-5)) ) + { + if ( !sendCommand( message ) ) + return( -1 ); + lastKeepalive = now; + } + usleep( 100000 ); + } #if 0 - message = "PAUSE "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; - if ( !sendCommand( message ) ) - return( -1 ); - if ( !recvResponse( response ) ) - return( -1 ); + message = "PAUSE "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; + if ( !sendCommand( message ) ) + return( -1 ); + if ( !recvResponse( response ) ) + return( -1 ); #endif - message = "TEARDOWN "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; - if ( !sendCommand( message ) ) - return( -1 ); - if ( !recvResponse( response ) ) - return( -1 ); + message = "TEARDOWN "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; + if ( !sendCommand( message ) ) + return( -1 ); + if ( !recvResponse( response ) ) + return( -1 ); - rtpDataThread.stop(); - rtpCtrlThread.stop(); + rtpDataThread.stop(); + rtpCtrlThread.stop(); - //rtpDataThread.kill( SIGTERM ); - //rtpCtrlThread.kill( SIGTERM ); + //rtpDataThread.kill( SIGTERM ); + //rtpCtrlThread.kill( SIGTERM ); - rtpDataThread.join(); - rtpCtrlThread.join(); - - delete mSources[ssrc]; - mSources.clear(); + rtpDataThread.join(); + rtpCtrlThread.join(); + + delete mSources[ssrc]; + mSources.clear(); - releasePorts( localPorts[0] ); + releasePorts( localPorts[0] ); - break; - } - case RTP_RTSP : - case RTP_RTSP_HTTP : - { - RtpSource *source = new RtpSource( mId, "", remoteChannels[0], mHost, remoteChannels[0], ssrc, seq, rtpClock, rtpTime, codecId ); - mSources[ssrc] = source; - // These never actually run - RtpDataThread rtpDataThread( *this, *source ); - RtpCtrlThread rtpCtrlThread( *this, *source ); - - Select select( double(config.http_timeout)/1000.0 ); - select.addReader( &mRtspSocket ); - - Buffer buffer( ZM_NETWORK_BUFSIZ ); - std::string keepaliveMessage = "OPTIONS "+mUrl+" RTSP/1.0\r\n"; - std::string keepaliveResponse = "RTSP/1.0 200 OK\r\n"; - while ( !mStop && select.wait() >= 0 ) - { - Select::CommsList readable = select.getReadable(); - if ( readable.size() == 0 ) - { - Error( "RTSP timed out" ); - break; - } - - static char tempBuffer[ZM_NETWORK_BUFSIZ]; - ssize_t nBytes = mRtspSocket.recv( tempBuffer, sizeof(tempBuffer) ); - buffer.append( tempBuffer, nBytes ); - Debug( 4, "Read %zd bytes on sd %d, %d total", nBytes, mRtspSocket.getReadDesc(), buffer.size() ); - - while( buffer.size() > 0 ) - { - if ( buffer[0] == '$' ) - { - if ( buffer.size() < 4 ) - break; - unsigned char channel = buffer[1]; - unsigned short len = ntohs( *((unsigned short *)(buffer+2)) ); - - Debug( 4, "Got %d bytes left, expecting %d byte packet on channel %d", buffer.size(), len, channel ); - if ( (unsigned short)buffer.size() < (len+4) ) - { - Debug( 4, "Missing %d bytes, rereading", (len+4)-buffer.size() ); - break; - } - if ( channel == remoteChannels[0] ) - { - Debug( 4, "Got %d bytes on data channel %d, packet length is %d", buffer.size(), channel, len ); - Hexdump( 4, (char *)buffer, 16 ); - rtpDataThread.recvPacket( buffer+4, len ); - Debug( 4, "Received" ); - } - else if ( channel == remoteChannels[1] ) - { -// len = ntohs( *((unsigned short *)(buffer+2)) ); -// Debug( 4, "Got %d bytes on control channel %d", nBytes, channel ); - Debug( 4, "Got %d bytes on control channel %d, packet length is %d", buffer.size(), channel, len ); - Hexdump( 4, (char *)buffer, 16 ); - rtpCtrlThread.recvPackets( buffer+4, len ); - } - else - { - Error( "Unexpected channel selector %d in RTSP interleaved data", buffer[1] ); - buffer.clear(); - break; - } - buffer.consume( len+4 ); - nBytes -= len+4; - } - else - { - if ( keepaliveResponse.compare( 0, keepaliveResponse.size(), (char *)buffer, keepaliveResponse.size() ) == 0 ) - { - Debug( 4, "Got keepalive response '%s'", (char *)buffer ); - //buffer.consume( keepaliveResponse.size() ); - if ( char *charPtr = (char *)memchr( (char *)buffer, '$', buffer.size() ) ) - { - int discardBytes = charPtr-(char *)buffer; - buffer -= discardBytes; - } - else - { - buffer.clear(); - } - } - else - { - if ( char *charPtr = (char *)memchr( (char *)buffer, '$', buffer.size() ) ) - { - int discardBytes = charPtr-(char *)buffer; - Warning( "Unexpected format RTSP interleaved data, resyncing by %d bytes", discardBytes ); - Hexdump( -1, (char *)buffer, discardBytes ); - buffer -= discardBytes; - } - else - { - Warning( "Unexpected format RTSP interleaved data, dumping %d bytes", buffer.size() ); - Hexdump( -1, (char *)buffer, 32 ); - buffer.clear(); - } - } - } - } - // Send a keepalive message if the server supports this feature and we are close to the timeout expiration - // FIXME: Is this really necessary when using tcp ? - now = time(NULL); - // Send a keepalive message if the server supports this feature and we are close to the timeout expiration -Debug(5, "sendkeepalive %d, timeout %d, now: %d last: %d since: %d", sendKeepalive, timeout, now, lastKeepalive, (now-lastKeepalive) ); - if ( sendKeepalive && (timeout > 0) && ((now-lastKeepalive) > (timeout-5)) ) - { - if ( !sendCommand( message ) ) - return( -1 ); - lastKeepalive = now; - } - buffer.tidy( 1 ); - } -#if 0 - message = "PAUSE "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; - if ( !sendCommand( message ) ) - return( -1 ); - if ( !recvResponse( response ) ) - return( -1 ); -#endif - // Send a teardown message but don't expect a response as this may not be implemented on the server when using TCP - message = "TEARDOWN "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; - if ( !sendCommand( message ) ) - return( -1 ); - - delete mSources[ssrc]; - mSources.clear(); - - break; - } - case RTP_MULTICAST : - { - RtpSource *source = new RtpSource( mId, localHost, localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime, codecId ); - mSources[ssrc] = source; - RtpDataThread rtpDataThread( *this, *source ); - RtpCtrlThread rtpCtrlThread( *this, *source ); - - rtpDataThread.start(); - rtpCtrlThread.start(); - - while( !mStop ) - { - // Send a keepalive message if the server supports this feature and we are close to the timeout expiration - if ( sendKeepalive && (timeout > 0) && ((time(NULL)-lastKeepalive) > (timeout-5)) ) - { - if ( !sendCommand( message ) ) - return( -1 ); - lastKeepalive = time(NULL); - } - usleep( 100000 ); - } -#if 0 - message = "PAUSE "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; - if ( !sendCommand( message ) ) - return( -1 ); - if ( !recvResponse( response ) ) - return( -1 ); -#endif - message = "TEARDOWN "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; - if ( !sendCommand( message ) ) - return( -1 ); - if ( !recvResponse( response ) ) - return( -1 ); - - rtpDataThread.stop(); - rtpCtrlThread.stop(); - - rtpDataThread.join(); - rtpCtrlThread.join(); - - delete mSources[ssrc]; - mSources.clear(); - - releasePorts( localPorts[0] ); - break; - } - default: - { - Panic( "Got unexpected method %d", mMethod ); - break; - } + break; } + case RTP_RTSP : + case RTP_RTSP_HTTP : + { + RtpSource *source = new RtpSource( mId, "", remoteChannels[0], mHost, remoteChannels[0], ssrc, seq, rtpClock, rtpTime, codecId ); + mSources[ssrc] = source; + // These never actually run + RtpDataThread rtpDataThread( *this, *source ); + RtpCtrlThread rtpCtrlThread( *this, *source ); - return( 0 ); + Select select( double(config.http_timeout)/1000.0 ); + select.addReader( &mRtspSocket ); + + Buffer buffer( ZM_NETWORK_BUFSIZ ); + std::string keepaliveMessage = "OPTIONS "+mUrl+" RTSP/1.0\r\n"; + std::string keepaliveResponse = "RTSP/1.0 200 OK\r\n"; + while ( !mStop && select.wait() >= 0 ) + { + Select::CommsList readable = select.getReadable(); + if ( readable.size() == 0 ) + { + Error( "RTSP timed out" ); + break; + } + + static char tempBuffer[ZM_NETWORK_BUFSIZ]; + ssize_t nBytes = mRtspSocket.recv( tempBuffer, sizeof(tempBuffer) ); + buffer.append( tempBuffer, nBytes ); + Debug( 4, "Read %zd bytes on sd %d, %d total", nBytes, mRtspSocket.getReadDesc(), buffer.size() ); + + while( buffer.size() > 0 ) + { + if ( buffer[0] == '$' ) + { + if ( buffer.size() < 4 ) + break; + unsigned char channel = buffer[1]; + unsigned short len = ntohs( *((unsigned short *)(buffer+2)) ); + + Debug( 4, "Got %d bytes left, expecting %d byte packet on channel %d", buffer.size(), len, channel ); + if ( (unsigned short)buffer.size() < (len+4) ) + { + Debug( 4, "Missing %d bytes, rereading", (len+4)-buffer.size() ); + break; + } + if ( channel == remoteChannels[0] ) + { + Debug( 4, "Got %d bytes on data channel %d, packet length is %d", buffer.size(), channel, len ); + Hexdump( 4, (char *)buffer, 16 ); + rtpDataThread.recvPacket( buffer+4, len ); + Debug( 4, "Received" ); + } + else if ( channel == remoteChannels[1] ) + { +// len = ntohs( *((unsigned short *)(buffer+2)) ); +// Debug( 4, "Got %d bytes on control channel %d", nBytes, channel ); + Debug( 4, "Got %d bytes on control channel %d, packet length is %d", buffer.size(), channel, len ); + Hexdump( 4, (char *)buffer, 16 ); + rtpCtrlThread.recvPackets( buffer+4, len ); + } + else + { + Error( "Unexpected channel selector %d in RTSP interleaved data", buffer[1] ); + buffer.clear(); + break; + } + buffer.consume( len+4 ); + nBytes -= len+4; + } + else + { + if ( keepaliveResponse.compare( 0, keepaliveResponse.size(), (char *)buffer, keepaliveResponse.size() ) == 0 ) + { + Debug( 4, "Got keepalive response '%s'", (char *)buffer ); + //buffer.consume( keepaliveResponse.size() ); + if ( char *charPtr = (char *)memchr( (char *)buffer, '$', buffer.size() ) ) + { + int discardBytes = charPtr-(char *)buffer; + buffer -= discardBytes; + } + else + { + buffer.clear(); + } + } + else + { + if ( char *charPtr = (char *)memchr( (char *)buffer, '$', buffer.size() ) ) + { + int discardBytes = charPtr-(char *)buffer; + Warning( "Unexpected format RTSP interleaved data, resyncing by %d bytes", discardBytes ); + Hexdump( -1, (char *)buffer, discardBytes ); + buffer -= discardBytes; + } + else + { + Warning( "Unexpected format RTSP interleaved data, dumping %d bytes", buffer.size() ); + Hexdump( -1, (char *)buffer, 32 ); + buffer.clear(); + } + } + } + } + // Send a keepalive message if the server supports this feature and we are close to the timeout expiration + // FIXME: Is this really necessary when using tcp ? + now = time(NULL); + // Send a keepalive message if the server supports this feature and we are close to the timeout expiration +Debug(5, "sendkeepalive %d, timeout %d, now: %d last: %d since: %d", sendKeepalive, timeout, now, lastKeepalive, (now-lastKeepalive) ); + if ( sendKeepalive && (timeout > 0) && ((now-lastKeepalive) > (timeout-5)) ) + { + if ( !sendCommand( message ) ) + return( -1 ); + lastKeepalive = now; + } + buffer.tidy( 1 ); + } +#if 0 + message = "PAUSE "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; + if ( !sendCommand( message ) ) + return( -1 ); + if ( !recvResponse( response ) ) + return( -1 ); +#endif + // Send a teardown message but don't expect a response as this may not be implemented on the server when using TCP + message = "TEARDOWN "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; + if ( !sendCommand( message ) ) + return( -1 ); + + delete mSources[ssrc]; + mSources.clear(); + + break; + } + case RTP_MULTICAST : + { + RtpSource *source = new RtpSource( mId, localHost, localPorts[0], mHost, remotePorts[0], ssrc, seq, rtpClock, rtpTime, codecId ); + mSources[ssrc] = source; + RtpDataThread rtpDataThread( *this, *source ); + RtpCtrlThread rtpCtrlThread( *this, *source ); + + rtpDataThread.start(); + rtpCtrlThread.start(); + + while( !mStop ) + { + // Send a keepalive message if the server supports this feature and we are close to the timeout expiration + if ( sendKeepalive && (timeout > 0) && ((time(NULL)-lastKeepalive) > (timeout-5)) ) + { + if ( !sendCommand( message ) ) + return( -1 ); + lastKeepalive = time(NULL); + } + usleep( 100000 ); + } +#if 0 + message = "PAUSE "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; + if ( !sendCommand( message ) ) + return( -1 ); + if ( !recvResponse( response ) ) + return( -1 ); +#endif + message = "TEARDOWN "+mUrl+" RTSP/1.0\r\nSession: "+session+"\r\n"; + if ( !sendCommand( message ) ) + return( -1 ); + if ( !recvResponse( response ) ) + return( -1 ); + + rtpDataThread.stop(); + rtpCtrlThread.stop(); + + rtpDataThread.join(); + rtpCtrlThread.join(); + + delete mSources[ssrc]; + mSources.clear(); + + releasePorts( localPorts[0] ); + break; + } + default: + { + Panic( "Got unexpected method %d", mMethod ); + break; + } + } + + return( 0 ); } #endif // HAVE_LIBAVFORMAT diff --git a/src/zm_rtsp.h b/src/zm_rtsp.h index 192200d0b..bdd14da42 100644 --- a/src/zm_rtsp.h +++ b/src/zm_rtsp.h @@ -34,110 +34,110 @@ class RtspThread : public Thread { public: - typedef enum { RTP_UNICAST, RTP_MULTICAST, RTP_RTSP, RTP_RTSP_HTTP } RtspMethod; - typedef enum { UNDEFINED, UNICAST, MULTICAST } RtspDist; + typedef enum { RTP_UNICAST, RTP_MULTICAST, RTP_RTSP, RTP_RTSP_HTTP } RtspMethod; + typedef enum { UNDEFINED, UNICAST, MULTICAST } RtspDist; private: - typedef std::set PortSet; - typedef std::set SsrcSet; - typedef std::map SourceMap; + typedef std::set PortSet; + typedef std::set SsrcSet; + typedef std::map SourceMap; private: - static int smMinDataPort; - static int smMaxDataPort; - static PortSet smLocalSsrcs; - static PortSet smAssignedPorts; + static int smMinDataPort; + static int smMaxDataPort; + static PortSet smLocalSsrcs; + static PortSet smAssignedPorts; private: - int mId; + int mId; - RtspMethod mMethod; - std::string mProtocol; - std::string mHost; - std::string mPort; - std::string mPath; - bool mRtspDescribe; - std::string mUrl; - - // Reworked authentication system - // First try without authentication, even if we have a username and password - // on receiving a 401 response, select authentication method (basic or digest) - // fill required fields and set needAuth - // subsequent requests can set the required authentication header. - bool mNeedAuth; - int respCode; - zm::Authenticator* mAuthenticator; + RtspMethod mMethod; + std::string mProtocol; + std::string mHost; + std::string mPort; + std::string mPath; + bool mRtspDescribe; + std::string mUrl; + + // Reworked authentication system + // First try without authentication, even if we have a username and password + // on receiving a 401 response, select authentication method (basic or digest) + // fill required fields and set needAuth + // subsequent requests can set the required authentication header. + bool mNeedAuth; + int respCode; + zm::Authenticator* mAuthenticator; - std::string mHttpSession; ///< Only for RTSP over HTTP sessions + std::string mHttpSession; ///< Only for RTSP over HTTP sessions - TcpInetClient mRtspSocket; - TcpInetClient mRtspSocket2; + TcpInetClient mRtspSocket; + TcpInetClient mRtspSocket2; - SourceMap mSources; + SourceMap mSources; - SessionDescriptor *mSessDesc; - AVFormatContext *mFormatContext; + SessionDescriptor *mSessDesc; + AVFormatContext *mFormatContext; - uint16_t mSeq; - uint32_t mSession; - uint32_t mSsrc; + uint16_t mSeq; + uint32_t mSession; + uint32_t mSsrc; - int mRemotePorts[2]; - int mRemoteChannels[2]; - RtspDist mDist; + int mRemotePorts[2]; + int mRemoteChannels[2]; + RtspDist mDist; - unsigned long mRtpTime; + unsigned long mRtpTime; - bool mStop; + bool mStop; private: - bool sendCommand( std::string message ); - bool recvResponse( std::string &response ); - void checkAuthResponse(std::string &response); + bool sendCommand( std::string message ); + bool recvResponse( std::string &response ); + void checkAuthResponse(std::string &response); public: - RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth, bool rtsp_describe ); - ~RtspThread(); + RtspThread( int id, RtspMethod method, const std::string &protocol, const std::string &host, const std::string &port, const std::string &path, const std::string &auth, bool rtsp_describe ); + ~RtspThread(); public: - int requestPorts(); - void releasePorts( int port ); + int requestPorts(); + void releasePorts( int port ); - bool isValidSsrc( uint32_t ssrc ); - bool updateSsrc( uint32_t ssrc, const RtpDataHeader *header ); + bool isValidSsrc( uint32_t ssrc ); + bool updateSsrc( uint32_t ssrc, const RtpDataHeader *header ); - uint32_t getSsrc() const - { - return( mSsrc ); - } + uint32_t getSsrc() const + { + return( mSsrc ); + } - bool hasSources() const - { - return( !mSources.empty() ); - } + bool hasSources() const + { + return( !mSources.empty() ); + } - AVFormatContext *getFormatContext() - { - return( mFormatContext ); - } - - bool getFrame( Buffer &frame ) - { - SourceMap::iterator iter = mSources.begin(); - if ( iter == mSources.end() ) - return( false ); - return( iter->second->getFrame( frame ) ); - } - int run(); - void stop() - { - mStop = true; - } - bool stopped() const - { - return( mStop ); - } + AVFormatContext *getFormatContext() + { + return( mFormatContext ); + } + + bool getFrame( Buffer &frame ) + { + SourceMap::iterator iter = mSources.begin(); + if ( iter == mSources.end() ) + return( false ); + return( iter->second->getFrame( frame ) ); + } + int run(); + void stop() + { + mStop = true; + } + bool stopped() const + { + return( mStop ); + } }; #endif // ZM_RTSP_H diff --git a/src/zm_rtsp_auth.cpp b/src/zm_rtsp_auth.cpp index 9521a81d1..4f816b64a 100644 --- a/src/zm_rtsp_auth.cpp +++ b/src/zm_rtsp_auth.cpp @@ -28,206 +28,206 @@ namespace zm { Authenticator::Authenticator(std::string &username, std::string password) { #ifdef HAVE_GCRYPT_H - // Special initialisation for libgcrypt - if ( !gcry_check_version( GCRYPT_VERSION ) ) - { - Fatal( "Unable to initialise libgcrypt" ); - } - gcry_control( GCRYCTL_DISABLE_SECMEM, 0 ); - gcry_control( GCRYCTL_INITIALIZATION_FINISHED, 0 ); + // Special initialisation for libgcrypt + if ( !gcry_check_version( GCRYPT_VERSION ) ) + { + Fatal( "Unable to initialise libgcrypt" ); + } + gcry_control( GCRYCTL_DISABLE_SECMEM, 0 ); + gcry_control( GCRYCTL_INITIALIZATION_FINISHED, 0 ); #endif // HAVE_GCRYPT_H - - fAuthMethod = AUTH_UNDEFINED; - fUsername = username; - fPassword = password; - nc = 1; - fCnonce = "0a4f113b"; + + fAuthMethod = AUTH_UNDEFINED; + fUsername = username; + fPassword = password; + nc = 1; + fCnonce = "0a4f113b"; } Authenticator::~Authenticator() { - reset(); + reset(); } void Authenticator::reset() { - fRealm.clear(); - fNonce.clear(); - fUsername.clear(); - fPassword.clear(); - fAuthMethod = AUTH_UNDEFINED; + fRealm.clear(); + fNonce.clear(); + fUsername.clear(); + fPassword.clear(); + fAuthMethod = AUTH_UNDEFINED; } void Authenticator::authHandleHeader(std::string headerData) { - const char* basic_match = "Basic "; - const char* digest_match = "Digest "; - size_t digest_match_len = strlen(digest_match); - - // Check if basic auth - if (strncasecmp(headerData.c_str(),basic_match,strlen(basic_match)) == 0) + const char* basic_match = "Basic "; + const char* digest_match = "Digest "; + size_t digest_match_len = strlen(digest_match); + + // Check if basic auth + if (strncasecmp(headerData.c_str(),basic_match,strlen(basic_match)) == 0) + { + fAuthMethod = AUTH_BASIC; + Debug( 2, "Set authMethod to Basic"); + } + // Check if digest auth + else if (strncasecmp( headerData.c_str(),digest_match,digest_match_len ) == 0) + { + fAuthMethod = AUTH_DIGEST; + Debug( 2, "Set authMethod to Digest"); + StringVector subparts = split(headerData.substr(digest_match_len, headerData.length() - digest_match_len), ","); + // subparts are key="value" + for ( size_t i = 0; i < subparts.size(); i++ ) { - fAuthMethod = AUTH_BASIC; - Debug( 2, "Set authMethod to Basic"); - } - // Check if digest auth - else if (strncasecmp( headerData.c_str(),digest_match,digest_match_len ) == 0) - { - fAuthMethod = AUTH_DIGEST; - Debug( 2, "Set authMethod to Digest"); - StringVector subparts = split(headerData.substr(digest_match_len, headerData.length() - digest_match_len), ","); - // subparts are key="value" - for ( size_t i = 0; i < subparts.size(); i++ ) - { - StringVector kvPair = split( trimSpaces( subparts[i] ), "=" ); - std::string key = trimSpaces( kvPair[0] ); - if (key == "realm") { - fRealm = trimSet( kvPair[1], "\""); - continue; - } - if (key == "nonce") { - fNonce = trimSet( kvPair[1], "\""); - continue; - } - if (key == "qop") { - fQop = trimSet( kvPair[1], "\""); - continue; - } - } - Debug( 2, "Auth data completed. User: %s, realm: %s, nonce: %s, qop: %s", username().c_str(), fRealm.c_str(), fNonce.c_str(), fQop.c_str() ); + StringVector kvPair = split( trimSpaces( subparts[i] ), "=" ); + std::string key = trimSpaces( kvPair[0] ); + if (key == "realm") { + fRealm = trimSet( kvPair[1], "\""); + continue; + } + if (key == "nonce") { + fNonce = trimSet( kvPair[1], "\""); + continue; + } + if (key == "qop") { + fQop = trimSet( kvPair[1], "\""); + continue; + } } + Debug( 2, "Auth data completed. User: %s, realm: %s, nonce: %s, qop: %s", username().c_str(), fRealm.c_str(), fNonce.c_str(), fQop.c_str() ); + } } std::string Authenticator::quote(std::string src) { - return replaceAll(replaceAll(src, "\\", "\\\\"), "\"", "\\\""); + return replaceAll(replaceAll(src, "\\", "\\\\"), "\"", "\\\""); } std::string Authenticator::getAuthHeader(std::string method, std::string uri) { - std::string result = "Authorization: "; - if (fAuthMethod == AUTH_BASIC) - { - result += "Basic " + base64Encode( username() + ":" + password() ); + std::string result = "Authorization: "; + if (fAuthMethod == AUTH_BASIC) + { + result += "Basic " + base64Encode( username() + ":" + password() ); + } + else if (fAuthMethod == AUTH_DIGEST) + { + result += std::string("Digest ") + + "username=\"" + quote(username()) + "\", realm=\"" + quote(realm()) + "\", " + + "nonce=\"" + quote(nonce()) + "\", uri=\"" + quote(uri) + "\""; + if ( ! fQop.empty() ) { + result += ", qop=" + fQop; + result += ", nc=" + stringtf("%08x",nc); + result += ", cnonce=\"" + fCnonce + "\""; } - else if (fAuthMethod == AUTH_DIGEST) - { - result += std::string("Digest ") + - "username=\"" + quote(username()) + "\", realm=\"" + quote(realm()) + "\", " + - "nonce=\"" + quote(nonce()) + "\", uri=\"" + quote(uri) + "\""; - if ( ! fQop.empty() ) { - result += ", qop=" + fQop; - result += ", nc=" + stringtf("%08x",nc); - result += ", cnonce=\"" + fCnonce + "\""; - } - result += ", response=\"" + computeDigestResponse(method, uri) + "\""; - result += ", algorithm=\"MD5\""; - - //Authorization: Digest username="zm", - // realm="NC-336PW-HD-1080P", - // nonce="de8859d97609a6fcc16eaba490dcfd80", - // uri="rtsp://10.192.16.8:554/live/0/h264.sdp", - // response="4092120557d3099a163bd51a0d59744d", - // algorithm=MD5, - // opaque="5ccc069c403ebaf9f0171e9517f40e41", - // qop="auth", - // cnonce="c8051140765877dc", - // nc=00000001 - - } - result += "\r\n"; - return result; + result += ", response=\"" + computeDigestResponse(method, uri) + "\""; + result += ", algorithm=\"MD5\""; + + //Authorization: Digest username="zm", + // realm="NC-336PW-HD-1080P", + // nonce="de8859d97609a6fcc16eaba490dcfd80", + // uri="rtsp://10.192.16.8:554/live/0/h264.sdp", + // response="4092120557d3099a163bd51a0d59744d", + // algorithm=MD5, + // opaque="5ccc069c403ebaf9f0171e9517f40e41", + // qop="auth", + // cnonce="c8051140765877dc", + // nc=00000001 + + } + result += "\r\n"; + return result; } std::string Authenticator::computeDigestResponse(std::string &method, std::string &uri) { #if HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT - // The "response" field is computed as: - // md5(md5(::)::md5(:)) - size_t md5len = 16; - unsigned char md5buf[md5len]; - char md5HexBuf[md5len*2+1]; - - // Step 1: md5(::) - std::string ha1Data = username() + ":" + realm() + ":" + password(); - Debug( 2, "HA1 pre-md5: %s", ha1Data.c_str() ); + // The "response" field is computed as: + // md5(md5(::)::md5(:)) + size_t md5len = 16; + unsigned char md5buf[md5len]; + char md5HexBuf[md5len*2+1]; + + // Step 1: md5(::) + std::string ha1Data = username() + ":" + realm() + ":" + password(); + Debug( 2, "HA1 pre-md5: %s", ha1Data.c_str() ); #if HAVE_DECL_MD5 - MD5((unsigned char*)ha1Data.c_str(), ha1Data.length(), md5buf); + MD5((unsigned char*)ha1Data.c_str(), ha1Data.length(), md5buf); #elif HAVE_DECL_GNUTLS_FINGERPRINT - gnutls_datum_t md5dataha1 = { (unsigned char*)ha1Data.c_str(), ha1Data.length() }; - gnutls_fingerprint( GNUTLS_DIG_MD5, &md5dataha1, md5buf, &md5len ); + gnutls_datum_t md5dataha1 = { (unsigned char*)ha1Data.c_str(), ha1Data.length() }; + gnutls_fingerprint( GNUTLS_DIG_MD5, &md5dataha1, md5buf, &md5len ); #endif - for ( unsigned int j = 0; j < md5len; j++ ) - { - sprintf(&md5HexBuf[2*j], "%02x", md5buf[j] ); - } - md5HexBuf[md5len*2]='\0'; - std::string ha1Hash = md5HexBuf; - - // Step 2: md5(:) - std::string ha2Data = method + ":" + uri; - Debug( 2, "HA2 pre-md5: %s", ha2Data.c_str() ); + for ( unsigned int j = 0; j < md5len; j++ ) + { + sprintf(&md5HexBuf[2*j], "%02x", md5buf[j] ); + } + md5HexBuf[md5len*2]='\0'; + std::string ha1Hash = md5HexBuf; + + // Step 2: md5(:) + std::string ha2Data = method + ":" + uri; + Debug( 2, "HA2 pre-md5: %s", ha2Data.c_str() ); #if HAVE_DECL_MD5 - MD5((unsigned char*)ha2Data.c_str(), ha2Data.length(), md5buf ); + MD5((unsigned char*)ha2Data.c_str(), ha2Data.length(), md5buf ); #elif HAVE_DECL_GNUTLS_FINGERPRINT - gnutls_datum_t md5dataha2 = { (unsigned char*)ha2Data.c_str(), ha2Data.length() }; - gnutls_fingerprint( GNUTLS_DIG_MD5, &md5dataha2, md5buf, &md5len ); + gnutls_datum_t md5dataha2 = { (unsigned char*)ha2Data.c_str(), ha2Data.length() }; + gnutls_fingerprint( GNUTLS_DIG_MD5, &md5dataha2, md5buf, &md5len ); #endif - for ( unsigned int j = 0; j < md5len; j++ ) - { - sprintf( &md5HexBuf[2*j], "%02x", md5buf[j] ); - } - md5HexBuf[md5len*2]='\0'; - std::string ha2Hash = md5HexBuf; + for ( unsigned int j = 0; j < md5len; j++ ) + { + sprintf( &md5HexBuf[2*j], "%02x", md5buf[j] ); + } + md5HexBuf[md5len*2]='\0'; + std::string ha2Hash = md5HexBuf; - // Step 3: md5(ha1::ha2) - std::string digestData = ha1Hash + ":" + nonce(); - if ( ! fQop.empty() ) { - digestData += ":" + stringtf("%08x", nc) + ":"+fCnonce + ":" + fQop; - nc ++; - // if qop was specified, then we have to include t and a cnonce and an nccount - } - digestData += ":" + ha2Hash; - Debug( 2, "pre-md5: %s", digestData.c_str() ); + // Step 3: md5(ha1::ha2) + std::string digestData = ha1Hash + ":" + nonce(); + if ( ! fQop.empty() ) { + digestData += ":" + stringtf("%08x", nc) + ":"+fCnonce + ":" + fQop; + nc ++; + // if qop was specified, then we have to include t and a cnonce and an nccount + } + digestData += ":" + ha2Hash; + Debug( 2, "pre-md5: %s", digestData.c_str() ); #if HAVE_DECL_MD5 - MD5((unsigned char*)digestData.c_str(), digestData.length(), md5buf); + MD5((unsigned char*)digestData.c_str(), digestData.length(), md5buf); #elif HAVE_DECL_GNUTLS_FINGERPRINT - gnutls_datum_t md5datadigest = { (unsigned char*)digestData.c_str(), digestData.length() }; - gnutls_fingerprint( GNUTLS_DIG_MD5, &md5datadigest, md5buf, &md5len ); + gnutls_datum_t md5datadigest = { (unsigned char*)digestData.c_str(), digestData.length() }; + gnutls_fingerprint( GNUTLS_DIG_MD5, &md5datadigest, md5buf, &md5len ); #endif - for ( unsigned int j = 0; j < md5len; j++ ) - { - sprintf( &md5HexBuf[2*j], "%02x", md5buf[j] ); - } - md5HexBuf[md5len*2]='\0'; + for ( unsigned int j = 0; j < md5len; j++ ) + { + sprintf( &md5HexBuf[2*j], "%02x", md5buf[j] ); + } + md5HexBuf[md5len*2]='\0'; - return md5HexBuf; + return md5HexBuf; #else // HAVE_DECL_MD5 - Error( "You need to build with gnutls or openssl installed to use digest authentication" ); - return( 0 ); + Error( "You need to build with gnutls or openssl installed to use digest authentication" ); + return( 0 ); #endif // HAVE_DECL_MD5 } void Authenticator::checkAuthResponse(std::string &response) { - std::string authLine; - StringVector lines = split( response, "\r\n" ); - const char* authenticate_match = "WWW-Authenticate:"; - size_t authenticate_match_len = strlen(authenticate_match); + std::string authLine; + StringVector lines = split( response, "\r\n" ); + const char* authenticate_match = "WWW-Authenticate:"; + size_t authenticate_match_len = strlen(authenticate_match); - for ( size_t i = 0; i < lines.size(); i++ ) { - // stop at end of headers - if (lines[i].length()==0) - break; + for ( size_t i = 0; i < lines.size(); i++ ) { + // stop at end of headers + if (lines[i].length()==0) + break; - if (strncasecmp(lines[i].c_str(),authenticate_match,authenticate_match_len) == 0) { - authLine = lines[i]; - Debug( 2, "Found auth line at %d", i); - break; - } - } - if (!authLine.empty()) { - Debug( 2, "Analyze auth line %s", authLine.c_str()); - authHandleHeader( trimSpaces(authLine.substr(authenticate_match_len,authLine.length()-authenticate_match_len)) ); - } else { - Debug( 2, "Didn't find auth line in %s", authLine.c_str()); - } + if (strncasecmp(lines[i].c_str(),authenticate_match,authenticate_match_len) == 0) { + authLine = lines[i]; + Debug( 2, "Found auth line at %d", i); + break; + } + } + if (!authLine.empty()) { + Debug( 2, "Analyze auth line %s", authLine.c_str()); + authHandleHeader( trimSpaces(authLine.substr(authenticate_match_len,authLine.length()-authenticate_match_len)) ); + } else { + Debug( 2, "Didn't find auth line in %s", authLine.c_str()); + } } } // namespace zm diff --git a/src/zm_rtsp_auth.h b/src/zm_rtsp_auth.h index 079dec639..9249a15e2 100644 --- a/src/zm_rtsp_auth.h +++ b/src/zm_rtsp_auth.h @@ -37,20 +37,20 @@ namespace zm { enum AuthMethod { AUTH_UNDEFINED = 0, AUTH_BASIC = 1, AUTH_DIGEST = 2 }; class Authenticator { public: - Authenticator(std::string &username, std::string password); - virtual ~Authenticator(); - void reset(); + Authenticator(std::string &username, std::string password); + virtual ~Authenticator(); + void reset(); - std::string realm() { return fRealm; } - std::string nonce() { return fNonce; } - std::string username() { return fUsername; } - AuthMethod auth_method() const { return fAuthMethod; } - - std::string computeDigestResponse( std::string &cmd, std::string &url ); - void authHandleHeader( std::string headerData ); - std::string getAuthHeader( std::string method, std::string path ); - void checkAuthResponse(std::string &response); - + std::string realm() { return fRealm; } + std::string nonce() { return fNonce; } + std::string username() { return fUsername; } + AuthMethod auth_method() const { return fAuthMethod; } + + std::string computeDigestResponse( std::string &cmd, std::string &url ); + void authHandleHeader( std::string headerData ); + std::string getAuthHeader( std::string method, std::string path ); + void checkAuthResponse(std::string &response); + private: std::string password() { return fPassword; } AuthMethod fAuthMethod; @@ -61,7 +61,7 @@ private: std::string fUsername; std::string fPassword; std::string quote( std::string src ); - int nc; + int nc; }; } // namespace zm diff --git a/src/zm_sdp.cpp b/src/zm_sdp.cpp index dbc63a82f..7bfc4b1f9 100644 --- a/src/zm_sdp.cpp +++ b/src/zm_sdp.cpp @@ -25,489 +25,489 @@ #if (LIBAVCODEC_VERSION_CHECK(52, 64, 0, 64, 0) || LIBAVUTIL_VERSION_CHECK(50, 14, 0, 14, 0)) SessionDescriptor::StaticPayloadDesc SessionDescriptor::smStaticPayloads[] = { - { 0, "PCMU", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_MULAW, 8000, 1 }, - { 3, "GSM", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, - { 4, "G723", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, - { 5, "DVI4", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, - { 6, "DVI4", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 16000, 1 }, - { 7, "LPC", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, - { 8, "PCMA", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_ALAW, 8000, 1 }, - { 9, "G722", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, - { 10, "L16", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_S16BE, 44100, 2 }, - { 11, "L16", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_S16BE, 44100, 1 }, - { 12, "QCELP", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_QCELP, 8000, 1 }, - { 13, "CN", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, - { 14, "MPA", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP2, -1, -1 }, - { 14, "MPA", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3, -1, -1 }, - { 15, "G728", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, - { 16, "DVI4", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 11025, 1 }, - { 17, "DVI4", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 22050, 1 }, - { 18, "G729", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, - { 25, "CelB", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_NONE, 90000, -1 }, - { 26, "JPEG", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MJPEG, 90000, -1 }, - { 28, "nv", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_NONE, 90000, -1 }, - { 31, "H261", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H261, 90000, -1 }, - { 32, "MPV", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG1VIDEO, 90000, -1 }, - { 32, "MPV", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO, 90000, -1 }, - { 33, "MP2T", AVMEDIA_TYPE_DATA, AV_CODEC_ID_MPEG2TS, 90000, -1 }, - { 34, "H263", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H263, 90000, -1 }, - { -1, "", AVMEDIA_TYPE_UNKNOWN, AV_CODEC_ID_NONE, -1, -1 } + { 0, "PCMU", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_MULAW, 8000, 1 }, + { 3, "GSM", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, + { 4, "G723", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, + { 5, "DVI4", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, + { 6, "DVI4", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 16000, 1 }, + { 7, "LPC", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, + { 8, "PCMA", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_ALAW, 8000, 1 }, + { 9, "G722", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, + { 10, "L16", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_S16BE, 44100, 2 }, + { 11, "L16", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_S16BE, 44100, 1 }, + { 12, "QCELP", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_QCELP, 8000, 1 }, + { 13, "CN", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, + { 14, "MPA", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP2, -1, -1 }, + { 14, "MPA", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3, -1, -1 }, + { 15, "G728", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, + { 16, "DVI4", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 11025, 1 }, + { 17, "DVI4", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 22050, 1 }, + { 18, "G729", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_NONE, 8000, 1 }, + { 25, "CelB", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_NONE, 90000, -1 }, + { 26, "JPEG", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MJPEG, 90000, -1 }, + { 28, "nv", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_NONE, 90000, -1 }, + { 31, "H261", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H261, 90000, -1 }, + { 32, "MPV", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG1VIDEO, 90000, -1 }, + { 32, "MPV", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO, 90000, -1 }, + { 33, "MP2T", AVMEDIA_TYPE_DATA, AV_CODEC_ID_MPEG2TS, 90000, -1 }, + { 34, "H263", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H263, 90000, -1 }, + { -1, "", AVMEDIA_TYPE_UNKNOWN, AV_CODEC_ID_NONE, -1, -1 } }; SessionDescriptor::DynamicPayloadDesc SessionDescriptor::smDynamicPayloads[] = { - { "MP4V-ES", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4 }, - { "mpeg4-generic", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC }, - { "H264", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 }, - { "AMR", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AMR_NB }, - { "vnd.onvif.metadata", AVMEDIA_TYPE_DATA, AV_CODEC_ID_NONE } + { "MP4V-ES", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4 }, + { "mpeg4-generic", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC }, + { "H264", AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 }, + { "AMR", AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AMR_NB }, + { "vnd.onvif.metadata", AVMEDIA_TYPE_DATA, AV_CODEC_ID_NONE } }; #else SessionDescriptor::StaticPayloadDesc SessionDescriptor::smStaticPayloads[] = { - { 0, "PCMU", CODEC_TYPE_AUDIO, CODEC_ID_PCM_MULAW, 8001, 1 }, - { 3, "GSM", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, - { 4, "G723", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, - { 5, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, - { 6, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 16000, 1 }, - { 7, "LPC", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, - { 8, "PCMA", CODEC_TYPE_AUDIO, CODEC_ID_PCM_ALAW, 8000, 1 }, - { 9, "G722", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, - { 10, "L16", CODEC_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 2 }, - { 11, "L16", CODEC_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 1 }, - { 12, "QCELP", CODEC_TYPE_AUDIO, CODEC_ID_QCELP, 8000, 1 }, - { 13, "CN", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, - { 14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP2, -1, -1 }, - { 14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP3, -1, -1 }, - { 15, "G728", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, - { 16, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 11025, 1 }, - { 17, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 22050, 1 }, - { 18, "G729", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, - { 25, "CelB", CODEC_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1 }, - { 26, "JPEG", CODEC_TYPE_VIDEO, CODEC_ID_MJPEG, 90000, -1 }, - { 28, "nv", CODEC_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1 }, - { 31, "H261", CODEC_TYPE_VIDEO, CODEC_ID_H261, 90000, -1 }, - { 32, "MPV", CODEC_TYPE_VIDEO, CODEC_ID_MPEG1VIDEO, 90000, -1 }, - { 32, "MPV", CODEC_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO, 90000, -1 }, - { 33, "MP2T", CODEC_TYPE_DATA, CODEC_ID_MPEG2TS, 90000, -1 }, - { 34, "H263", CODEC_TYPE_VIDEO, CODEC_ID_H263, 90000, -1 }, - { -1, "", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1 } + { 0, "PCMU", CODEC_TYPE_AUDIO, CODEC_ID_PCM_MULAW, 8001, 1 }, + { 3, "GSM", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, + { 4, "G723", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, + { 5, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, + { 6, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 16000, 1 }, + { 7, "LPC", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, + { 8, "PCMA", CODEC_TYPE_AUDIO, CODEC_ID_PCM_ALAW, 8000, 1 }, + { 9, "G722", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, + { 10, "L16", CODEC_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 2 }, + { 11, "L16", CODEC_TYPE_AUDIO, CODEC_ID_PCM_S16BE, 44100, 1 }, + { 12, "QCELP", CODEC_TYPE_AUDIO, CODEC_ID_QCELP, 8000, 1 }, + { 13, "CN", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, + { 14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP2, -1, -1 }, + { 14, "MPA", CODEC_TYPE_AUDIO, CODEC_ID_MP3, -1, -1 }, + { 15, "G728", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, + { 16, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 11025, 1 }, + { 17, "DVI4", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 22050, 1 }, + { 18, "G729", CODEC_TYPE_AUDIO, CODEC_ID_NONE, 8000, 1 }, + { 25, "CelB", CODEC_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1 }, + { 26, "JPEG", CODEC_TYPE_VIDEO, CODEC_ID_MJPEG, 90000, -1 }, + { 28, "nv", CODEC_TYPE_VIDEO, CODEC_ID_NONE, 90000, -1 }, + { 31, "H261", CODEC_TYPE_VIDEO, CODEC_ID_H261, 90000, -1 }, + { 32, "MPV", CODEC_TYPE_VIDEO, CODEC_ID_MPEG1VIDEO, 90000, -1 }, + { 32, "MPV", CODEC_TYPE_VIDEO, CODEC_ID_MPEG2VIDEO, 90000, -1 }, + { 33, "MP2T", CODEC_TYPE_DATA, CODEC_ID_MPEG2TS, 90000, -1 }, + { 34, "H263", CODEC_TYPE_VIDEO, CODEC_ID_H263, 90000, -1 }, + { -1, "", CODEC_TYPE_UNKNOWN, CODEC_ID_NONE, -1, -1 } }; SessionDescriptor::DynamicPayloadDesc SessionDescriptor::smDynamicPayloads[] = { - { "MP4V-ES", CODEC_TYPE_VIDEO, CODEC_ID_MPEG4 }, - { "mpeg4-generic", CODEC_TYPE_AUDIO, CODEC_ID_AAC }, - { "H264", CODEC_TYPE_VIDEO, CODEC_ID_H264 }, - { "AMR", CODEC_TYPE_AUDIO, CODEC_ID_AMR_NB }, - { "vnd.onvif.metadata", CODEC_TYPE_DATA, CODEC_ID_NONE } + { "MP4V-ES", CODEC_TYPE_VIDEO, CODEC_ID_MPEG4 }, + { "mpeg4-generic", CODEC_TYPE_AUDIO, CODEC_ID_AAC }, + { "H264", CODEC_TYPE_VIDEO, CODEC_ID_H264 }, + { "AMR", CODEC_TYPE_AUDIO, CODEC_ID_AMR_NB }, + { "vnd.onvif.metadata", CODEC_TYPE_DATA, CODEC_ID_NONE } }; #endif SessionDescriptor::ConnInfo::ConnInfo( const std::string &connInfo ) : - mTtl( 16 ), - mNoAddresses( 0 ) + mTtl( 16 ), + mNoAddresses( 0 ) { - StringVector tokens = split( connInfo, " " ); - if ( tokens.size() < 3 ) - throw Exception( "Unable to parse SDP connection info from '"+connInfo+"'" ); - mNetworkType = tokens[0]; - if ( mNetworkType != "IN" ) - throw Exception( "Invalid SDP network type '"+mNetworkType+"' in connection info '"+connInfo+"'" ); - mAddressType = tokens[1]; - if ( mAddressType != "IP4" ) - throw Exception( "Invalid SDP address type '"+mAddressType+"' in connection info '"+connInfo+"'" ); - StringVector addressTokens = split( tokens[2], "/" ); - if ( addressTokens.size() < 1 ) - throw Exception( "Invalid SDP address '"+tokens[2]+"' in connection info '"+connInfo+"'" ); - mAddress = addressTokens[0]; - if ( addressTokens.size() >= 2 ) - mTtl = atoi(addressTokens[1].c_str()); - if ( addressTokens.size() >= 3 ) - mNoAddresses = atoi(addressTokens[2].c_str()); + StringVector tokens = split( connInfo, " " ); + if ( tokens.size() < 3 ) + throw Exception( "Unable to parse SDP connection info from '"+connInfo+"'" ); + mNetworkType = tokens[0]; + if ( mNetworkType != "IN" ) + throw Exception( "Invalid SDP network type '"+mNetworkType+"' in connection info '"+connInfo+"'" ); + mAddressType = tokens[1]; + if ( mAddressType != "IP4" ) + throw Exception( "Invalid SDP address type '"+mAddressType+"' in connection info '"+connInfo+"'" ); + StringVector addressTokens = split( tokens[2], "/" ); + if ( addressTokens.size() < 1 ) + throw Exception( "Invalid SDP address '"+tokens[2]+"' in connection info '"+connInfo+"'" ); + mAddress = addressTokens[0]; + if ( addressTokens.size() >= 2 ) + mTtl = atoi(addressTokens[1].c_str()); + if ( addressTokens.size() >= 3 ) + mNoAddresses = atoi(addressTokens[2].c_str()); } SessionDescriptor::BandInfo::BandInfo( const std::string &bandInfo ) : - mValue( 0 ) + mValue( 0 ) { - StringVector tokens = split( bandInfo, ":" ); - if ( tokens.size() < 2 ) - throw Exception( "Unable to parse SDP bandwidth info from '"+bandInfo+"'" ); - mType = tokens[0]; - //if ( mNetworkType != "IN" ) - //throw Exception( "Invalid SDP network type '"+mNetworkType+"' in connection info '"+connInfo+"'" ); - mValue = atoi(tokens[1].c_str()); + StringVector tokens = split( bandInfo, ":" ); + if ( tokens.size() < 2 ) + throw Exception( "Unable to parse SDP bandwidth info from '"+bandInfo+"'" ); + mType = tokens[0]; + //if ( mNetworkType != "IN" ) + //throw Exception( "Invalid SDP network type '"+mNetworkType+"' in connection info '"+connInfo+"'" ); + mValue = atoi(tokens[1].c_str()); } SessionDescriptor::MediaDescriptor::MediaDescriptor( const std::string &type, int port, int numPorts, const std::string &transport, int payloadType ) : - mType( type ), - mPort( port ), - mNumPorts( numPorts ), - mTransport( transport ), - mPayloadType( payloadType ), - mFrameRate( 0.0 ), - mClock( 0 ), - mWidth( 0 ), - mHeight( 0 ), - mSprops( "" ), - mConnInfo( 0 ) + mType( type ), + mPort( port ), + mNumPorts( numPorts ), + mTransport( transport ), + mPayloadType( payloadType ), + mFrameRate( 0.0 ), + mClock( 0 ), + mWidth( 0 ), + mHeight( 0 ), + mSprops( "" ), + mConnInfo( 0 ) { } SessionDescriptor::SessionDescriptor( const std::string &url, const std::string &sdp ) : - mUrl( url ), - mConnInfo( 0 ), - mBandInfo( 0 ) + mUrl( url ), + mConnInfo( 0 ), + mBandInfo( 0 ) { - MediaDescriptor *currMedia = 0; + MediaDescriptor *currMedia = 0; - StringVector lines = split( sdp, "\r\n" ); - for ( StringVector::const_iterator iter = lines.begin(); iter != lines.end(); iter++ ) + StringVector lines = split( sdp, "\r\n" ); + for ( StringVector::const_iterator iter = lines.begin(); iter != lines.end(); iter++ ) + { + std::string line = *iter; + if ( line.empty() ) + break; + + Debug( 3, "Processing SDP line '%s'", line.c_str() ); + const char sdpType = line[0]; + if ( line[1] != '=' ) + throw Exception( "Invalid SDP format at '"+line+"'" ); + + line.erase( 0, 2 ); + switch( sdpType ) { - std::string line = *iter; - if ( line.empty() ) - break; - - Debug( 3, "Processing SDP line '%s'", line.c_str() ); - const char sdpType = line[0]; - if ( line[1] != '=' ) - throw Exception( "Invalid SDP format at '"+line+"'" ); - - line.erase( 0, 2 ); - switch( sdpType ) + case 'v' : + mVersion = line; + break; + case 'o' : + mOwner = line; + break; + case 's' : + mName = line; + break; + case 'i' : + mInfo = line; + break; + case 'c' : + // This prevent a memory leak if the field appears more than one time + if ( mConnInfo ) + delete mConnInfo; + mConnInfo = new ConnInfo( line ); + break; + case 'b' : + // This prevent a memory leak if the field appears more than one time + if ( mBandInfo ) + delete mBandInfo; + mBandInfo = new BandInfo( line ); + break; + case 't' : + mTimeInfo = line; + break; + case 'a' : + { + mAttributes.push_back( line ); + StringVector tokens = split( line, ":", 2 ); + std::string attrName = tokens[0]; + if ( currMedia ) { - case 'v' : - mVersion = line; - break; - case 'o' : - mOwner = line; - break; - case 's' : - mName = line; - break; - case 'i' : - mInfo = line; - break; - case 'c' : - // This prevent a memory leak if the field appears more than one time - if ( mConnInfo ) - delete mConnInfo; - mConnInfo = new ConnInfo( line ); - break; - case 'b' : - // This prevent a memory leak if the field appears more than one time - if ( mBandInfo ) - delete mBandInfo; - mBandInfo = new BandInfo( line ); - break; - case 't' : - mTimeInfo = line; - break; - case 'a' : + if ( attrName == "control" ) + { + if ( tokens.size() < 2 ) + throw Exception( "Unable to parse SDP control attribute '"+line+"' for media '"+currMedia->getType()+"'" ); + currMedia->setControlUrl( tokens[1] ); + } + else if ( attrName == "range" ) + { + } + else if ( attrName == "rtpmap" ) + { + // a=rtpmap:96 MP4V-ES/90000 + if ( tokens.size() < 2 ) + throw Exception( "Unable to parse SDP rtpmap attribute '"+line+"' for media '"+currMedia->getType()+"'" ); + StringVector attrTokens = split( tokens[1], " " ); + int payloadType = atoi(attrTokens[0].c_str()); + if ( payloadType != currMedia->getPayloadType() ) + throw Exception( stringtf( "Payload type mismatch, expected %d, got %d in '%s'", currMedia->getPayloadType(), payloadType, line.c_str() ) ); + std::string payloadDesc = attrTokens[1]; + //currMedia->setPayloadType( payloadType ); + if ( attrTokens.size() > 1 ) { - mAttributes.push_back( line ); - StringVector tokens = split( line, ":", 2 ); - std::string attrName = tokens[0]; - if ( currMedia ) - { - if ( attrName == "control" ) - { - if ( tokens.size() < 2 ) - throw Exception( "Unable to parse SDP control attribute '"+line+"' for media '"+currMedia->getType()+"'" ); - currMedia->setControlUrl( tokens[1] ); - } - else if ( attrName == "range" ) - { - } - else if ( attrName == "rtpmap" ) - { - // a=rtpmap:96 MP4V-ES/90000 - if ( tokens.size() < 2 ) - throw Exception( "Unable to parse SDP rtpmap attribute '"+line+"' for media '"+currMedia->getType()+"'" ); - StringVector attrTokens = split( tokens[1], " " ); - int payloadType = atoi(attrTokens[0].c_str()); - if ( payloadType != currMedia->getPayloadType() ) - throw Exception( stringtf( "Payload type mismatch, expected %d, got %d in '%s'", currMedia->getPayloadType(), payloadType, line.c_str() ) ); - std::string payloadDesc = attrTokens[1]; - //currMedia->setPayloadType( payloadType ); - if ( attrTokens.size() > 1 ) - { - StringVector payloadTokens = split( attrTokens[1], "/" ); - std::string payloadDesc = payloadTokens[0]; - int payloadClock = atoi(payloadTokens[1].c_str()); - currMedia->setPayloadDesc( payloadDesc ); - currMedia->setClock( payloadClock ); - } - } - else if ( attrName == "framesize" ) - { - // a=framesize:96 320-240 - if ( tokens.size() < 2 ) - throw Exception( "Unable to parse SDP framesize attribute '"+line+"' for media '"+currMedia->getType()+"'" ); - StringVector attrTokens = split( tokens[1], " " ); - int payloadType = atoi(attrTokens[0].c_str()); - if ( payloadType != currMedia->getPayloadType() ) - throw Exception( stringtf( "Payload type mismatch, expected %d, got %d in '%s'", currMedia->getPayloadType(), payloadType, line.c_str() ) ); - //currMedia->setPayloadType( payloadType ); - StringVector sizeTokens = split( attrTokens[1], "-" ); - int width = atoi(sizeTokens[0].c_str()); - int height = atoi(sizeTokens[1].c_str()); - currMedia->setFrameSize( width, height ); - } - else if ( attrName == "framerate" ) - { - // a=framerate:5.0 - if ( tokens.size() < 2 ) - throw Exception( "Unable to parse SDP framerate attribute '"+line+"' for media '"+currMedia->getType()+"'" ); - double frameRate = atof(tokens[1].c_str()); - currMedia->setFrameRate( frameRate ); - } - else if ( attrName == "fmtp" ) - { - // a=fmtp:96 profile-level-id=247; config=000001B0F7000001B509000001000000012008D48D8803250F042D14440F - if ( tokens.size() < 2 ) - throw Exception( "Unable to parse SDP fmtp attribute '"+line+"' for media '"+currMedia->getType()+"'" ); - StringVector attrTokens = split( tokens[1], " ", 2 ); - int payloadType = atoi(attrTokens[0].c_str()); - if ( payloadType != currMedia->getPayloadType() ) - throw Exception( stringtf( "Payload type mismatch, expected %d, got %d in '%s'", currMedia->getPayloadType(), payloadType, line.c_str() ) ); - //currMedia->setPayloadType( payloadType ); - if ( attrTokens.size() > 1 ) - { - StringVector attr2Tokens = split( attrTokens[1], "; " ); - for ( unsigned int i = 0; i < attr2Tokens.size(); i++ ) - { - StringVector attr3Tokens = split( attr2Tokens[i], "=" ); - //Info( "Name = %s, Value = %s", attr3Tokens[0].c_str(), attr3Tokens[1].c_str() ); - if ( attr3Tokens[0] == "profile-level-id" ) - { - } - else if ( attr3Tokens[0] == "config" ) - { - } - else if ( attr3Tokens[0] == "sprop-parameter-sets" ) - { - size_t t = attr2Tokens[i].find("="); - char *c = (char *)attr2Tokens[i].c_str() + t + 1; - Debug(4, "sprop-parameter-sets value %s", c); - currMedia->setSprops(std::string(c)); - } - else if ( attr3Tokens[0] == "sprop-parameter-sets" ) - { - size_t t = attr2Tokens[i].find("="); - char *c = (char *)attr2Tokens[i].c_str() + t + 1; - Debug(4, "sprop-parameter-sets value %s", c); - currMedia->setSprops(std::string(c)); - } - else - { - Debug( 3, "Ignoring SDP fmtp attribute '%s' for media '%s'", attr3Tokens[0].c_str(), currMedia->getType().c_str() ) - } - } - } - } - else if ( attrName == "mpeg4-iod" ) - { - // a=mpeg4-iod: "data:application/mpeg4-iod;base64,AoEAAE8BAf73AQOAkwABQHRkYXRhOmFwcGxpY2F0aW9uL21wZWc0LW9kLWF1O2Jhc2U2NCxBVGdCR3dVZkF4Y0F5U1FBWlFRTklCRUVrK0FBQWEyd0FBR3RzQVlCQkFFWkFwOERGUUJsQlFRTlFCVUFDN2dBQVBvQUFBRDZBQVlCQXc9PQQNAQUABAAAAAAAAAAAAAYJAQAAAAAAAAAAA0IAAkA+ZGF0YTphcHBsaWNhdGlvbi9tcGVnNC1iaWZzLWF1O2Jhc2U2NCx3QkFTZ1RBcUJYSmhCSWhRUlFVL0FBPT0EEgINAAACAAAAAAAAAAAFAwAAQAYJAQAAAAAAAAAA" - } - else if ( attrName == "mpeg4-esid" ) - { - // a=mpeg4-esid:201 - } - else - { - Debug( 3, "Ignoring SDP attribute '%s' for media '%s'", line.c_str(), currMedia->getType().c_str() ) - } - } - else - { - Debug( 3, "Ignoring general SDP attribute '%s'", line.c_str() ); - } - break; + StringVector payloadTokens = split( attrTokens[1], "/" ); + std::string payloadDesc = payloadTokens[0]; + int payloadClock = atoi(payloadTokens[1].c_str()); + currMedia->setPayloadDesc( payloadDesc ); + currMedia->setClock( payloadClock ); } - case 'm' : + } + else if ( attrName == "framesize" ) + { + // a=framesize:96 320-240 + if ( tokens.size() < 2 ) + throw Exception( "Unable to parse SDP framesize attribute '"+line+"' for media '"+currMedia->getType()+"'" ); + StringVector attrTokens = split( tokens[1], " " ); + int payloadType = atoi(attrTokens[0].c_str()); + if ( payloadType != currMedia->getPayloadType() ) + throw Exception( stringtf( "Payload type mismatch, expected %d, got %d in '%s'", currMedia->getPayloadType(), payloadType, line.c_str() ) ); + //currMedia->setPayloadType( payloadType ); + StringVector sizeTokens = split( attrTokens[1], "-" ); + int width = atoi(sizeTokens[0].c_str()); + int height = atoi(sizeTokens[1].c_str()); + currMedia->setFrameSize( width, height ); + } + else if ( attrName == "framerate" ) + { + // a=framerate:5.0 + if ( tokens.size() < 2 ) + throw Exception( "Unable to parse SDP framerate attribute '"+line+"' for media '"+currMedia->getType()+"'" ); + double frameRate = atof(tokens[1].c_str()); + currMedia->setFrameRate( frameRate ); + } + else if ( attrName == "fmtp" ) + { + // a=fmtp:96 profile-level-id=247; config=000001B0F7000001B509000001000000012008D48D8803250F042D14440F + if ( tokens.size() < 2 ) + throw Exception( "Unable to parse SDP fmtp attribute '"+line+"' for media '"+currMedia->getType()+"'" ); + StringVector attrTokens = split( tokens[1], " ", 2 ); + int payloadType = atoi(attrTokens[0].c_str()); + if ( payloadType != currMedia->getPayloadType() ) + throw Exception( stringtf( "Payload type mismatch, expected %d, got %d in '%s'", currMedia->getPayloadType(), payloadType, line.c_str() ) ); + //currMedia->setPayloadType( payloadType ); + if ( attrTokens.size() > 1 ) { - StringVector tokens = split( line, " " ); - if ( tokens.size() < 4 ) - throw Exception( "Can't parse SDP media description '"+line+"'" ); - std::string mediaType = tokens[0]; - if ( mediaType != "audio" && mediaType != "video" && mediaType != "application" ) - throw Exception( "Unsupported media type '"+mediaType+"' in SDP media attribute '"+line+"'" ); - StringVector portTokens = split( tokens[1], "/" ); - int mediaPort = atoi(portTokens[0].c_str()); - int mediaNumPorts = 1; - if ( portTokens.size() > 1 ) - mediaNumPorts = atoi(portTokens[1].c_str()); - std::string mediaTransport = tokens[2]; - if ( mediaTransport != "RTP/AVP" ) - throw Exception( "Unsupported media transport '"+mediaTransport+"' in SDP media attribute '"+line+"'" ); - int payloadType = atoi(tokens[3].c_str()); - currMedia = new MediaDescriptor( mediaType, mediaPort, mediaNumPorts, mediaTransport, payloadType ); - mMediaList.push_back( currMedia ); - break; + StringVector attr2Tokens = split( attrTokens[1], "; " ); + for ( unsigned int i = 0; i < attr2Tokens.size(); i++ ) + { + StringVector attr3Tokens = split( attr2Tokens[i], "=" ); + //Info( "Name = %s, Value = %s", attr3Tokens[0].c_str(), attr3Tokens[1].c_str() ); + if ( attr3Tokens[0] == "profile-level-id" ) + { + } + else if ( attr3Tokens[0] == "config" ) + { + } + else if ( attr3Tokens[0] == "sprop-parameter-sets" ) + { + size_t t = attr2Tokens[i].find("="); + char *c = (char *)attr2Tokens[i].c_str() + t + 1; + Debug(4, "sprop-parameter-sets value %s", c); + currMedia->setSprops(std::string(c)); + } + else if ( attr3Tokens[0] == "sprop-parameter-sets" ) + { + size_t t = attr2Tokens[i].find("="); + char *c = (char *)attr2Tokens[i].c_str() + t + 1; + Debug(4, "sprop-parameter-sets value %s", c); + currMedia->setSprops(std::string(c)); + } + else + { + Debug( 3, "Ignoring SDP fmtp attribute '%s' for media '%s'", attr3Tokens[0].c_str(), currMedia->getType().c_str() ) + } + } } + } + else if ( attrName == "mpeg4-iod" ) + { + // a=mpeg4-iod: "data:application/mpeg4-iod;base64,AoEAAE8BAf73AQOAkwABQHRkYXRhOmFwcGxpY2F0aW9uL21wZWc0LW9kLWF1O2Jhc2U2NCxBVGdCR3dVZkF4Y0F5U1FBWlFRTklCRUVrK0FBQWEyd0FBR3RzQVlCQkFFWkFwOERGUUJsQlFRTlFCVUFDN2dBQVBvQUFBRDZBQVlCQXc9PQQNAQUABAAAAAAAAAAAAAYJAQAAAAAAAAAAA0IAAkA+ZGF0YTphcHBsaWNhdGlvbi9tcGVnNC1iaWZzLWF1O2Jhc2U2NCx3QkFTZ1RBcUJYSmhCSWhRUlFVL0FBPT0EEgINAAACAAAAAAAAAAAFAwAAQAYJAQAAAAAAAAAA" + } + else if ( attrName == "mpeg4-esid" ) + { + // a=mpeg4-esid:201 + } + else + { + Debug( 3, "Ignoring SDP attribute '%s' for media '%s'", line.c_str(), currMedia->getType().c_str() ) + } } + else + { + Debug( 3, "Ignoring general SDP attribute '%s'", line.c_str() ); + } + break; + } + case 'm' : + { + StringVector tokens = split( line, " " ); + if ( tokens.size() < 4 ) + throw Exception( "Can't parse SDP media description '"+line+"'" ); + std::string mediaType = tokens[0]; + if ( mediaType != "audio" && mediaType != "video" && mediaType != "application" ) + throw Exception( "Unsupported media type '"+mediaType+"' in SDP media attribute '"+line+"'" ); + StringVector portTokens = split( tokens[1], "/" ); + int mediaPort = atoi(portTokens[0].c_str()); + int mediaNumPorts = 1; + if ( portTokens.size() > 1 ) + mediaNumPorts = atoi(portTokens[1].c_str()); + std::string mediaTransport = tokens[2]; + if ( mediaTransport != "RTP/AVP" ) + throw Exception( "Unsupported media transport '"+mediaTransport+"' in SDP media attribute '"+line+"'" ); + int payloadType = atoi(tokens[3].c_str()); + currMedia = new MediaDescriptor( mediaType, mediaPort, mediaNumPorts, mediaTransport, payloadType ); + mMediaList.push_back( currMedia ); + break; + } } + } } SessionDescriptor::~SessionDescriptor() { - if ( mConnInfo ) - delete mConnInfo; - if ( mBandInfo ) - delete mBandInfo; - for ( unsigned int i = 0; i < mMediaList.size(); i++ ) - delete mMediaList[i]; + if ( mConnInfo ) + delete mConnInfo; + if ( mBandInfo ) + delete mBandInfo; + for ( unsigned int i = 0; i < mMediaList.size(); i++ ) + delete mMediaList[i]; } AVFormatContext *SessionDescriptor::generateFormatContext() const { - AVFormatContext *formatContext = avformat_alloc_context(); + AVFormatContext *formatContext = avformat_alloc_context(); - strncpy( formatContext->filename, mUrl.c_str(), sizeof(formatContext->filename) ); + strncpy( formatContext->filename, mUrl.c_str(), sizeof(formatContext->filename) ); /* - if ( mName.length() ) - strncpy( formatContext->title, mName.c_str(), sizeof(formatContext->title) ); - if ( mInfo.length() ) - strncpy( formatContext->comment, mInfo.c_str(), sizeof(formatContext->comment) ); + if ( mName.length() ) + strncpy( formatContext->title, mName.c_str(), sizeof(formatContext->title) ); + if ( mInfo.length() ) + strncpy( formatContext->comment, mInfo.c_str(), sizeof(formatContext->comment) ); */ - //formatContext->nb_streams = mMediaList.size(); - for ( unsigned int i = 0; i < mMediaList.size(); i++ ) - { - const MediaDescriptor *mediaDesc = mMediaList[i]; + //formatContext->nb_streams = mMediaList.size(); + for ( unsigned int i = 0; i < mMediaList.size(); i++ ) + { + const MediaDescriptor *mediaDesc = mMediaList[i]; #if !LIBAVFORMAT_VERSION_CHECK(53, 10, 0, 17, 0) - AVStream *stream = av_new_stream( formatContext, i ); + AVStream *stream = av_new_stream( formatContext, i ); #else - AVStream *stream = avformat_new_stream( formatContext, NULL ); - stream->id = i; + AVStream *stream = avformat_new_stream( formatContext, NULL ); + stream->id = i; #endif - Debug( 1, "Looking for codec for %s payload type %d / %s", mediaDesc->getType().c_str(), mediaDesc->getPayloadType(), mediaDesc->getPayloadDesc().c_str() ); + Debug( 1, "Looking for codec for %s payload type %d / %s", mediaDesc->getType().c_str(), mediaDesc->getPayloadType(), mediaDesc->getPayloadDesc().c_str() ); #if (LIBAVCODEC_VERSION_CHECK(52, 64, 0, 64, 0) || LIBAVUTIL_VERSION_CHECK(50, 14, 0, 14, 0)) - if ( mediaDesc->getType() == "video" ) - stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; - else if ( mediaDesc->getType() == "audio" ) - stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; - else if ( mediaDesc->getType() == "application" ) - stream->codec->codec_type = AVMEDIA_TYPE_DATA; + if ( mediaDesc->getType() == "video" ) + stream->codec->codec_type = AVMEDIA_TYPE_VIDEO; + else if ( mediaDesc->getType() == "audio" ) + stream->codec->codec_type = AVMEDIA_TYPE_AUDIO; + else if ( mediaDesc->getType() == "application" ) + stream->codec->codec_type = AVMEDIA_TYPE_DATA; #else - if ( mediaDesc->getType() == "video" ) - stream->codec->codec_type = CODEC_TYPE_VIDEO; - else if ( mediaDesc->getType() == "audio" ) - stream->codec->codec_type = CODEC_TYPE_AUDIO; - else if ( mediaDesc->getType() == "application" ) - stream->codec->codec_type = CODEC_TYPE_DATA; + if ( mediaDesc->getType() == "video" ) + stream->codec->codec_type = CODEC_TYPE_VIDEO; + else if ( mediaDesc->getType() == "audio" ) + stream->codec->codec_type = CODEC_TYPE_AUDIO; + else if ( mediaDesc->getType() == "application" ) + stream->codec->codec_type = CODEC_TYPE_DATA; #endif #if LIBAVCODEC_VERSION_CHECK(55, 50, 3, 60, 103) - std::string codec_name; + std::string codec_name; #endif - if ( mediaDesc->getPayloadType() < PAYLOAD_TYPE_DYNAMIC ) + if ( mediaDesc->getPayloadType() < PAYLOAD_TYPE_DYNAMIC ) + { + // Look in static table + for ( unsigned int i = 0; i < (sizeof(smStaticPayloads)/sizeof(*smStaticPayloads)); i++ ) + { + if ( smStaticPayloads[i].payloadType == mediaDesc->getPayloadType() ) { - // Look in static table - for ( unsigned int i = 0; i < (sizeof(smStaticPayloads)/sizeof(*smStaticPayloads)); i++ ) - { - if ( smStaticPayloads[i].payloadType == mediaDesc->getPayloadType() ) - { - Debug( 1, "Got static payload type %d, %s", smStaticPayloads[i].payloadType, smStaticPayloads[i].payloadName ); + Debug( 1, "Got static payload type %d, %s", smStaticPayloads[i].payloadType, smStaticPayloads[i].payloadName ); #if LIBAVCODEC_VERSION_CHECK(55, 50, 3, 60, 103) - codec_name = std::string( smStaticPayloads[i].payloadName ); + codec_name = std::string( smStaticPayloads[i].payloadName ); #else - strncpy( stream->codec->codec_name, smStaticPayloads[i].payloadName, sizeof(stream->codec->codec_name) );; + strncpy( stream->codec->codec_name, smStaticPayloads[i].payloadName, sizeof(stream->codec->codec_name) );; #endif - stream->codec->codec_type = smStaticPayloads[i].codecType; - stream->codec->codec_id = smStaticPayloads[i].codecId; - stream->codec->sample_rate = smStaticPayloads[i].clockRate; - break; - } - } + stream->codec->codec_type = smStaticPayloads[i].codecType; + stream->codec->codec_id = smStaticPayloads[i].codecId; + stream->codec->sample_rate = smStaticPayloads[i].clockRate; + break; } - else + } + } + else + { + // Look in dynamic table + for ( unsigned int i = 0; i < (sizeof(smDynamicPayloads)/sizeof(*smDynamicPayloads)); i++ ) + { + if ( smDynamicPayloads[i].payloadName == mediaDesc->getPayloadDesc() ) { - // Look in dynamic table - for ( unsigned int i = 0; i < (sizeof(smDynamicPayloads)/sizeof(*smDynamicPayloads)); i++ ) - { - if ( smDynamicPayloads[i].payloadName == mediaDesc->getPayloadDesc() ) - { - Debug( 1, "Got dynamic payload type %d, %s", mediaDesc->getPayloadType(), smDynamicPayloads[i].payloadName ); + Debug( 1, "Got dynamic payload type %d, %s", mediaDesc->getPayloadType(), smDynamicPayloads[i].payloadName ); #if LIBAVCODEC_VERSION_CHECK(55, 50, 3, 60, 103) - codec_name = std::string( smStaticPayloads[i].payloadName ); + codec_name = std::string( smStaticPayloads[i].payloadName ); #else - strncpy( stream->codec->codec_name, smDynamicPayloads[i].payloadName, sizeof(stream->codec->codec_name) );; + strncpy( stream->codec->codec_name, smDynamicPayloads[i].payloadName, sizeof(stream->codec->codec_name) );; #endif - stream->codec->codec_type = smDynamicPayloads[i].codecType; - stream->codec->codec_id = smDynamicPayloads[i].codecId; - stream->codec->sample_rate = mediaDesc->getClock(); - break; - } - } - } - -#if LIBAVCODEC_VERSION_CHECK(55, 50, 3, 60, 103) - if ( codec_name.empty() ) -#else - if ( !stream->codec->codec_name[0] ) -#endif - { - Warning( "Can't find payload details for %s payload type %d, name %s", mediaDesc->getType().c_str(), mediaDesc->getPayloadType(), mediaDesc->getPayloadDesc().c_str() ); - //return( 0 ); - } - if ( mediaDesc->getWidth() ) - stream->codec->width = mediaDesc->getWidth(); - if ( mediaDesc->getHeight() ) - stream->codec->height = mediaDesc->getHeight(); - if ( stream->codec->codec_id == AV_CODEC_ID_H264 && mediaDesc->getSprops().size()) - { - uint8_t start_sequence[]= { 0, 0, 1 }; - stream->codec->extradata_size= 0; - stream->codec->extradata= NULL; - char pvalue[1024], *value = pvalue; - - strcpy(pvalue, mediaDesc->getSprops().c_str()); - - while (*value) { - char base64packet[1024]; - uint8_t decoded_packet[1024]; - uint32_t packet_size; - char *dst = base64packet; - - while (*value && *value != ',' - && (dst - base64packet) < (long)(sizeof(base64packet)) - 1) { - *dst++ = *value++; - } - *dst++ = '\0'; - - if (*value == ',') - value++; - - packet_size= av_base64_decode(decoded_packet, (const char *)base64packet, (int)sizeof(decoded_packet)); - Hexdump(4, (char *)decoded_packet, packet_size); - if (packet_size) { - uint8_t *dest = - (uint8_t *)av_malloc(packet_size + sizeof(start_sequence) + - stream->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if(dest) { - if(stream->codec->extradata_size) { - // av_realloc? - memcpy(dest, stream->codec->extradata, stream->codec->extradata_size); - av_free(stream->codec->extradata); - } - - memcpy(dest+stream->codec->extradata_size, start_sequence, sizeof(start_sequence)); - memcpy(dest+stream->codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size); - memset(dest+stream->codec->extradata_size+sizeof(start_sequence)+ - packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - - stream->codec->extradata= dest; - stream->codec->extradata_size+= sizeof(start_sequence)+packet_size; -// } else { -// av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!"); -// return AVERROR(ENOMEM); - } - } - } + stream->codec->codec_type = smDynamicPayloads[i].codecType; + stream->codec->codec_id = smDynamicPayloads[i].codecId; + stream->codec->sample_rate = mediaDesc->getClock(); + break; } + } } - return( formatContext ); +#if LIBAVCODEC_VERSION_CHECK(55, 50, 3, 60, 103) + if ( codec_name.empty() ) +#else + if ( !stream->codec->codec_name[0] ) +#endif + { + Warning( "Can't find payload details for %s payload type %d, name %s", mediaDesc->getType().c_str(), mediaDesc->getPayloadType(), mediaDesc->getPayloadDesc().c_str() ); + //return( 0 ); + } + if ( mediaDesc->getWidth() ) + stream->codec->width = mediaDesc->getWidth(); + if ( mediaDesc->getHeight() ) + stream->codec->height = mediaDesc->getHeight(); + if ( stream->codec->codec_id == AV_CODEC_ID_H264 && mediaDesc->getSprops().size()) + { + uint8_t start_sequence[]= { 0, 0, 1 }; + stream->codec->extradata_size= 0; + stream->codec->extradata= NULL; + char pvalue[1024], *value = pvalue; + + strcpy(pvalue, mediaDesc->getSprops().c_str()); + + while (*value) { + char base64packet[1024]; + uint8_t decoded_packet[1024]; + uint32_t packet_size; + char *dst = base64packet; + + while (*value && *value != ',' + && (dst - base64packet) < (long)(sizeof(base64packet)) - 1) { + *dst++ = *value++; + } + *dst++ = '\0'; + + if (*value == ',') + value++; + + packet_size= av_base64_decode(decoded_packet, (const char *)base64packet, (int)sizeof(decoded_packet)); + Hexdump(4, (char *)decoded_packet, packet_size); + if (packet_size) { + uint8_t *dest = + (uint8_t *)av_malloc(packet_size + sizeof(start_sequence) + + stream->codec->extradata_size + + FF_INPUT_BUFFER_PADDING_SIZE); + if(dest) { + if(stream->codec->extradata_size) { + // av_realloc? + memcpy(dest, stream->codec->extradata, stream->codec->extradata_size); + av_free(stream->codec->extradata); + } + + memcpy(dest+stream->codec->extradata_size, start_sequence, sizeof(start_sequence)); + memcpy(dest+stream->codec->extradata_size+sizeof(start_sequence), decoded_packet, packet_size); + memset(dest+stream->codec->extradata_size+sizeof(start_sequence)+ + packet_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + + stream->codec->extradata= dest; + stream->codec->extradata_size+= sizeof(start_sequence)+packet_size; +// } else { +// av_log(codec, AV_LOG_ERROR, "Unable to allocate memory for extradata!"); +// return AVERROR(ENOMEM); + } + } + } + } + } + + return( formatContext ); } #endif // HAVE_LIBAVFORMAT diff --git a/src/zm_sdp.h b/src/zm_sdp.h index 21eb227c1..2d08905c8 100644 --- a/src/zm_sdp.h +++ b/src/zm_sdp.h @@ -34,204 +34,204 @@ class SessionDescriptor { protected: - enum { PAYLOAD_TYPE_DYNAMIC=96 }; + enum { PAYLOAD_TYPE_DYNAMIC=96 }; - struct StaticPayloadDesc - { - int payloadType; - const char payloadName[6]; + struct StaticPayloadDesc + { + int payloadType; + const char payloadName[6]; #if (LIBAVCODEC_VERSION_CHECK(52, 64, 0, 64, 0) || LIBAVUTIL_VERSION_CHECK(50, 14, 0, 14, 0)) - AVMediaType codecType; + AVMediaType codecType; #else - enum CodecType codecType; + enum CodecType codecType; #endif - _AVCODECID codecId; - int clockRate; - int autoChannels; - }; + _AVCODECID codecId; + int clockRate; + int autoChannels; + }; - struct DynamicPayloadDesc - { - const char payloadName[32]; + struct DynamicPayloadDesc + { + const char payloadName[32]; #if (LIBAVCODEC_VERSION_CHECK(52, 64, 0, 64, 0) || LIBAVUTIL_VERSION_CHECK(50, 14, 0, 14, 0)) - AVMediaType codecType; + AVMediaType codecType; #else - enum CodecType codecType; + enum CodecType codecType; #endif - _AVCODECID codecId; + _AVCODECID codecId; - //int clockRate; - //int autoChannels; - }; + //int clockRate; + //int autoChannels; + }; public: - class ConnInfo - { - protected: - std::string mNetworkType; - std::string mAddressType; - std::string mAddress; - int mTtl; - int mNoAddresses; + class ConnInfo + { + protected: + std::string mNetworkType; + std::string mAddressType; + std::string mAddress; + int mTtl; + int mNoAddresses; - public: - ConnInfo( const std::string &connInfo ); - }; + public: + ConnInfo( const std::string &connInfo ); + }; - class BandInfo - { - protected: - std::string mType; - int mValue; + class BandInfo + { + protected: + std::string mType; + int mValue; - public: - BandInfo( const std::string &bandInfo ); - }; + public: + BandInfo( const std::string &bandInfo ); + }; - class MediaDescriptor - { - protected: - std::string mType; - int mPort; - int mNumPorts; - std::string mTransport; - int mPayloadType; + class MediaDescriptor + { + protected: + std::string mType; + int mPort; + int mNumPorts; + std::string mTransport; + int mPayloadType; - std::string mPayloadDesc; - std::string mControlUrl; - double mFrameRate; - int mClock; - int mWidth; - int mHeight; - std::string mSprops; - - ConnInfo *mConnInfo; - - public: - MediaDescriptor( const std::string &type, int port, int numPorts, const std::string &transport, int payloadType ); - - const std::string &getType() const - { - return( mType ); - } - int getPort() const - { - return( mPort ); - } - int getNumPorts() const - { - return( mNumPorts ); - } - const std::string &getTransport() const - { - return( mTransport ); - } - const int getPayloadType() const - { - return( mPayloadType ); - } - - const std::string &getPayloadDesc() const - { - return( mPayloadDesc ); - } - void setPayloadDesc( const std::string &payloadDesc ) - { - mPayloadDesc = payloadDesc; - } - - const std::string &getControlUrl() const - { - return( mControlUrl ); - } - void setControlUrl( const std::string &controlUrl ) - { - mControlUrl = controlUrl; - } - - const int getClock() const - { - return( mClock ); - } - void setClock( int clock ) - { - mClock = clock; - } - - void setFrameSize( int width, int height ) - { - mWidth = width; - mHeight = height; - } - int getWidth() const - { - return( mWidth ); - } - int getHeight() const - { - return( mHeight ); - } - - void setSprops(const std::string props) - { - mSprops = props; - } - const std::string getSprops() const - { - return ( mSprops ); - } - const double getFrameRate() const - { - return( mFrameRate ); - } - void setFrameRate( double frameRate ) - { - mFrameRate = frameRate; - } - }; - - typedef std::vector MediaList; - -protected: - static StaticPayloadDesc smStaticPayloads[]; - static DynamicPayloadDesc smDynamicPayloads[]; - -protected: - std::string mUrl; - - std::string mVersion; - std::string mOwner; - std::string mName; - std::string mInfo; + std::string mPayloadDesc; + std::string mControlUrl; + double mFrameRate; + int mClock; + int mWidth; + int mHeight; + std::string mSprops; ConnInfo *mConnInfo; - BandInfo *mBandInfo; - std::string mTimeInfo; - StringVector mAttributes; - MediaList mMediaList; + public: + MediaDescriptor( const std::string &type, int port, int numPorts, const std::string &transport, int payloadType ); + + const std::string &getType() const + { + return( mType ); + } + int getPort() const + { + return( mPort ); + } + int getNumPorts() const + { + return( mNumPorts ); + } + const std::string &getTransport() const + { + return( mTransport ); + } + const int getPayloadType() const + { + return( mPayloadType ); + } + + const std::string &getPayloadDesc() const + { + return( mPayloadDesc ); + } + void setPayloadDesc( const std::string &payloadDesc ) + { + mPayloadDesc = payloadDesc; + } + + const std::string &getControlUrl() const + { + return( mControlUrl ); + } + void setControlUrl( const std::string &controlUrl ) + { + mControlUrl = controlUrl; + } + + const int getClock() const + { + return( mClock ); + } + void setClock( int clock ) + { + mClock = clock; + } + + void setFrameSize( int width, int height ) + { + mWidth = width; + mHeight = height; + } + int getWidth() const + { + return( mWidth ); + } + int getHeight() const + { + return( mHeight ); + } + + void setSprops(const std::string props) + { + mSprops = props; + } + const std::string getSprops() const + { + return ( mSprops ); + } + const double getFrameRate() const + { + return( mFrameRate ); + } + void setFrameRate( double frameRate ) + { + mFrameRate = frameRate; + } + }; + + typedef std::vector MediaList; + +protected: + static StaticPayloadDesc smStaticPayloads[]; + static DynamicPayloadDesc smDynamicPayloads[]; + +protected: + std::string mUrl; + + std::string mVersion; + std::string mOwner; + std::string mName; + std::string mInfo; + + ConnInfo *mConnInfo; + BandInfo *mBandInfo; + std::string mTimeInfo; + StringVector mAttributes; + + MediaList mMediaList; public: - SessionDescriptor( const std::string &url, const std::string &sdp ); - ~SessionDescriptor(); + SessionDescriptor( const std::string &url, const std::string &sdp ); + ~SessionDescriptor(); - const std::string &getUrl() const - { - return( mUrl ); - } + const std::string &getUrl() const + { + return( mUrl ); + } - int getNumStreams() const - { - return( mMediaList.size() ); - } - MediaDescriptor *getStream( int index ) - { - if ( index < 0 || (unsigned int)index >= mMediaList.size() ) - return( 0 ); - return( mMediaList[index] ); - } + int getNumStreams() const + { + return( mMediaList.size() ); + } + MediaDescriptor *getStream( int index ) + { + if ( index < 0 || (unsigned int)index >= mMediaList.size() ) + return( 0 ); + return( mMediaList[index] ); + } - AVFormatContext *generateFormatContext() const; + AVFormatContext *generateFormatContext() const; }; #if 0 v=0 @@ -254,7 +254,7 @@ a=mpeg4-esid:201 m=audio 0 RTP/AVP 0 b=AS:64 a=control:trackID=2 - + #endif #endif // ZM_SDP_H diff --git a/src/zm_sendfile.h b/src/zm_sendfile.h index ce3405d66..0e35388ea 100644 --- a/src/zm_sendfile.h +++ b/src/zm_sendfile.h @@ -1,30 +1,30 @@ #ifdef HAVE_SENDFILE4_SUPPORT #include int zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) { - int err; + int err; - err = sendfile(out_fd, in_fd, offset, size); - if (err < 0) - return -errno; + err = sendfile(out_fd, in_fd, offset, size); + if (err < 0) + return -errno; - return err; + return err; } #elif HAVE_SENDFILE7_SUPPORT #include #include #include int zm_sendfile(int out_fd, int in_fd, off_t *offset, off_t size) { - int err; - err = sendfile(in_fd, out_fd, *offset, size, NULL, &size, 0); - if (err && errno != EAGAIN) - return -errno; + int err; + err = sendfile(in_fd, out_fd, *offset, size, NULL, &size, 0); + if (err && errno != EAGAIN) + return -errno; - if (size) { - *offset += size; - return size; - } + if (size) { + *offset += size; + return size; + } - return -EAGAIN; + return -EAGAIN; } #else #error "Your platform does not support sendfile. Sorry." diff --git a/src/zm_signal.cpp b/src/zm_signal.cpp index 91e1bc4ba..bbc40e916 100644 --- a/src/zm_signal.cpp +++ b/src/zm_signal.cpp @@ -47,15 +47,12 @@ RETSIGTYPE zm_die_handler(int signal, siginfo_t * info, void *context) RETSIGTYPE zm_die_handler(int signal) #endif { -#if (defined(__i386__) || defined(__x86_64__)) - void *cr2 = 0; - void *ip = 0; -#endif Error("Got signal %d (%s), crashing", signal, strsignal(signal)); - #if (defined(__i386__) || defined(__x86_64__)) // Get more information if available -#if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) + #if ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) + void *ip = 0; + void *cr2 = 0; if (info && context) { Debug(1, @@ -65,19 +62,19 @@ RETSIGTYPE zm_die_handler(int signal) ucontext_t *uc = (ucontext_t *) context; cr2 = info->si_addr; -#if defined(__x86_64__) - #ifdef __FreeBSD_kernel__ + #if defined(__x86_64__) + #ifdef __FreeBSD_kernel__ ip = (void *)(uc->uc_mcontext.mc_rip); - #else + #else ip = (void *)(uc->uc_mcontext.gregs[REG_RIP]); - #endif -#else - #ifdef __FreeBSD_kernel__ + #endif + #else + #ifdef __FreeBSD_kernel__ ip = (void *)(uc->uc_mcontext.mc_eip); - #else + #else ip = (void *)(uc->uc_mcontext.gregs[REG_EIP]); - #endif -#endif // defined(__x86_64__) + #endif + #endif // defined(__x86_64__) // Print the signal address and instruction pointer if available if (ip) { @@ -86,11 +83,11 @@ RETSIGTYPE zm_die_handler(int signal) Error("Signal address is %p, no instruction pointer", cr2); } } -#endif // ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) + #endif // ( HAVE_SIGINFO_T && HAVE_UCONTEXT_T ) // Print backtrace if enabled and available -#if ( !defined(ZM_NO_CRASHTRACE) && HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS ) + #if ( !defined(ZM_NO_CRASHTRACE) && HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS ) void *trace[TRACE_SIZE]; int trace_size = 0; trace_size = backtrace(trace, TRACE_SIZE); @@ -111,7 +108,7 @@ RETSIGTYPE zm_die_handler(int signal) Info("Backtrace complete, please execute the following command for more information"); Info(cmd); -#endif // ( !defined(ZM_NO_CRASHTRACE) && HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS ) + #endif // ( !defined(ZM_NO_CRASHTRACE) && HAVE_DECL_BACKTRACE && HAVE_DECL_BACKTRACE_SYMBOLS ) #endif // (defined(__i386__) || defined(__x86_64__) exit(signal); } diff --git a/src/zm_storage.cpp b/src/zm_storage.cpp index 14a6cfc01..ff2bce5a9 100644 --- a/src/zm_storage.cpp +++ b/src/zm_storage.cpp @@ -50,8 +50,8 @@ Storage::Storage( unsigned int p_id ) { char sql[ZM_SQL_SML_BUFSIZ]; snprintf( sql, sizeof(sql), "SELECT Id, Name, Path from Storage WHERE Id=%d", p_id ); Debug(1,"Loading Storage for %d using %s", p_id, sql ); - MYSQL_ROW dbrow = zmDbFetchOne( sql ); - if ( ! dbrow ) { + zmDbRow dbrow; + if ( ! dbrow.fetch( sql ) ) { Error( "Unable to load storage area for id %d: %s", p_id, mysql_error( &dbconn ) ); } else { unsigned int index = 0; diff --git a/src/zm_stream.cpp b/src/zm_stream.cpp index 77c94e68c..3bab38f86 100644 --- a/src/zm_stream.cpp +++ b/src/zm_stream.cpp @@ -32,326 +32,326 @@ StreamBase::~StreamBase() { #if HAVE_LIBAVCODEC - if ( vid_stream ) - { - delete vid_stream; - vid_stream = NULL; - } + if ( vid_stream ) + { + delete vid_stream; + vid_stream = NULL; + } #endif - closeComms(); + closeComms(); } bool StreamBase::loadMonitor( int monitor_id ) { - if ( !(monitor = Monitor::Load( monitor_id, false, Monitor::QUERY )) ) - { - Fatal( "Unable to load monitor id %d for streaming", monitor_id ); - return( false ); - } - monitor->connect(); - return( true ); + if ( !(monitor = Monitor::Load( monitor_id, false, Monitor::QUERY )) ) + { + Fatal( "Unable to load monitor id %d for streaming", monitor_id ); + return( false ); + } + monitor->connect(); + return( true ); } bool StreamBase::checkInitialised() { - if ( !monitor ) - { - Fatal( "Cannot stream, not initialised" ); - return( false ); - } - return( true ); + if ( !monitor ) + { + Fatal( "Cannot stream, not initialised" ); + return( false ); + } + return( true ); } void StreamBase::updateFrameRate( double fps ) { - base_fps = fps; - effective_fps = (base_fps*abs(replay_rate))/ZM_RATE_BASE; - frame_mod = 1; - Debug( 3, "FPS:%.2f, MXFPS:%.2f, BFPS:%.2f, EFPS:%.2f, FM:%d", fps, maxfps, base_fps, effective_fps, frame_mod ); - // Min frame repeat? - while( effective_fps > maxfps ) - { - effective_fps /= 2.0; - frame_mod *= 2; - } - Debug( 3, "aEFPS:%.2f, aFM:%d", effective_fps, frame_mod ); + base_fps = fps; + effective_fps = (base_fps*abs(replay_rate))/ZM_RATE_BASE; + frame_mod = 1; + Debug( 3, "FPS:%.2f, MXFPS:%.2f, BFPS:%.2f, EFPS:%.2f, FM:%d", fps, maxfps, base_fps, effective_fps, frame_mod ); + // Min frame repeat? + while( effective_fps > maxfps ) + { + effective_fps /= 2.0; + frame_mod *= 2; + } + Debug( 3, "aEFPS:%.2f, aFM:%d", effective_fps, frame_mod ); } bool StreamBase::checkCommandQueue() { - if ( sd >= 0 ) + if ( sd >= 0 ) + { + CmdMsg msg; + memset( &msg, 0, sizeof(msg) ); + int nbytes = recvfrom( sd, &msg, sizeof(msg), MSG_DONTWAIT, 0, 0 ); + if ( nbytes < 0 ) { - CmdMsg msg; - memset( &msg, 0, sizeof(msg) ); - int nbytes = recvfrom( sd, &msg, sizeof(msg), MSG_DONTWAIT, 0, 0 ); - if ( nbytes < 0 ) - { - if ( errno != EAGAIN ) - { - Fatal( "recvfrom(), errno = %d, error = %s", errno, strerror(errno) ); - } - } - //else if ( (nbytes != sizeof(msg)) ) - //{ - //Error( "Partial message received, expected %d bytes, got %d", sizeof(msg), nbytes ); - //} - else - { - processCommand( &msg ); - return( true ); - } + if ( errno != EAGAIN ) + { + Fatal( "recvfrom(), errno = %d, error = %s", errno, strerror(errno) ); + } } - return( false ); + //else if ( (nbytes != sizeof(msg)) ) + //{ + //Error( "Partial message received, expected %d bytes, got %d", sizeof(msg), nbytes ); + //} + else + { + processCommand( &msg ); + return( true ); + } + } + return( false ); } Image *StreamBase::prepareImage( Image *image ) { - static int last_scale = 0; - static int last_zoom = 0; - static int last_x = 0; - static int last_y = 0; + static int last_scale = 0; + static int last_zoom = 0; + static int last_x = 0; + static int last_y = 0; - if ( !last_scale ) - last_scale = scale; - if ( !last_zoom ) - last_zoom = zoom; - - // Do not bother to scale zoomed in images, just crop them and let the browser scale - // Works in FF2 but breaks FF3 which doesn't like image sizes changing in mid stream. - bool optimisedScaling = false; - - bool image_copied = false; - - int mag = (scale * zoom) / ZM_SCALE_BASE; - int act_mag = optimisedScaling?(mag > ZM_SCALE_BASE?ZM_SCALE_BASE:mag):mag; - Debug( 3, "Scaling by %d, zooming by %d = magnifying by %d(%d)", scale, zoom, mag, act_mag ); - - int last_mag = (last_scale * last_zoom) / ZM_SCALE_BASE; - int last_act_mag = last_mag > ZM_SCALE_BASE?ZM_SCALE_BASE:last_mag; - Debug( 3, "Last scaling by %d, zooming by %d = magnifying by %d(%d)", last_scale, last_zoom, last_mag, last_act_mag ); - - int base_image_width = image->Width(), base_image_height = image->Height(); - Debug( 3, "Base image width = %d, height = %d", base_image_width, base_image_height ); - - int virt_image_width = (base_image_width * mag) / ZM_SCALE_BASE, virt_image_height = (base_image_height * mag) / ZM_SCALE_BASE; - Debug( 3, "Virtual image width = %d, height = %d", virt_image_width, virt_image_height ); - - int last_virt_image_width = (base_image_width * last_mag) / ZM_SCALE_BASE, last_virt_image_height = (base_image_height * last_mag) / ZM_SCALE_BASE; - Debug( 3, "Last virtual image width = %d, height = %d", last_virt_image_width, last_virt_image_height ); - - int act_image_width = (base_image_width * act_mag ) / ZM_SCALE_BASE, act_image_height = (base_image_height * act_mag ) / ZM_SCALE_BASE; - Debug( 3, "Actual image width = %d, height = %d", act_image_width, act_image_height ); - - int last_act_image_width = (base_image_width * last_act_mag ) / ZM_SCALE_BASE, last_act_image_height = (base_image_height * last_act_mag ) / ZM_SCALE_BASE; - Debug( 3, "Last actual image width = %d, height = %d", last_act_image_width, last_act_image_height ); - - int disp_image_width = (image->Width() * scale) / ZM_SCALE_BASE, disp_image_height = (image->Height() * scale) / ZM_SCALE_BASE; - Debug( 3, "Display image width = %d, height = %d", disp_image_width, disp_image_height ); - - int last_disp_image_width = (image->Width() * last_scale) / ZM_SCALE_BASE, last_disp_image_height = (image->Height() * last_scale) / ZM_SCALE_BASE; - Debug( 3, "Last display image width = %d, height = %d", last_disp_image_width, last_disp_image_height ); - - int send_image_width = (disp_image_width * act_mag ) / mag, send_image_height = (disp_image_height * act_mag ) / mag; - Debug( 3, "Send image width = %d, height = %d", send_image_width, send_image_height ); - - int last_send_image_width = (last_disp_image_width * last_act_mag ) / last_mag, last_send_image_height = (last_disp_image_height * last_act_mag ) / last_mag; - Debug( 3, "Last send image width = %d, height = %d", last_send_image_width, last_send_image_height ); - - if ( mag != ZM_SCALE_BASE ) - { - if ( act_mag != ZM_SCALE_BASE ) - { - Debug( 3, "Magnifying by %d", mag ); - if ( !image_copied ) - { - static Image copy_image; - copy_image.Assign( *image ); - image = ©_image; - image_copied = true; - } - image->Scale( mag ); - } - } - - Debug( 3, "Real image width = %d, height = %d", image->Width(), image->Height() ); - - if ( disp_image_width < virt_image_width || disp_image_height < virt_image_height ) - { - static Box last_crop; - - if ( mag != last_mag || x != last_x || y != last_y ) - { - Debug( 3, "Got click at %d,%d x %d", x, y, mag ); - - //if ( !last_mag ) - //last_mag = mag; - - if ( !(last_disp_image_width < last_virt_image_width || last_disp_image_height < last_virt_image_height) ) - last_crop = Box(); - - Debug( 3, "Recalculating crop" ); - // Recalculate crop parameters, as %ges - int click_x = (last_crop.LoX() * 100 ) / last_act_image_width; // Initial crop offset from last image - click_x += ( x * 100 ) / last_virt_image_width; - int click_y = (last_crop.LoY() * 100 ) / last_act_image_height; // Initial crop offset from last image - click_y += ( y * 100 ) / last_virt_image_height; - Debug( 3, "Got adjusted click at %d%%,%d%%", click_x, click_y ); - - // Convert the click locations to the current image pixels - click_x = ( click_x * act_image_width ) / 100; - click_y = ( click_y * act_image_height ) / 100; - Debug( 3, "Got readjusted click at %d,%d", click_x, click_y ); - - int lo_x = click_x - (send_image_width/2); - if ( lo_x < 0 ) - lo_x = 0; - int hi_x = lo_x + (send_image_width-1); - if ( hi_x >= act_image_width ) - { - hi_x = act_image_width - 1; - lo_x = hi_x - (send_image_width - 1); - } - - int lo_y = click_y - (send_image_height/2); - if ( lo_y < 0 ) - lo_y = 0; - int hi_y = lo_y + (send_image_height-1); - if ( hi_y >= act_image_height ) - { - hi_y = act_image_height - 1; - lo_y = hi_y - (send_image_height - 1); - } - last_crop = Box( lo_x, lo_y, hi_x, hi_y ); - } - Debug( 3, "Cropping to %d,%d -> %d,%d", last_crop.LoX(), last_crop.LoY(), last_crop.HiX(), last_crop.HiY() ); - if ( !image_copied ) - { - static Image copy_image; - copy_image.Assign( *image ); - image = ©_image; - image_copied = true; - } - image->Crop( last_crop ); - } + if ( !last_scale ) last_scale = scale; + if ( !last_zoom ) last_zoom = zoom; - last_x = x; - last_y = y; - return( image ); + // Do not bother to scale zoomed in images, just crop them and let the browser scale + // Works in FF2 but breaks FF3 which doesn't like image sizes changing in mid stream. + bool optimisedScaling = false; + + bool image_copied = false; + + int mag = (scale * zoom) / ZM_SCALE_BASE; + int act_mag = optimisedScaling?(mag > ZM_SCALE_BASE?ZM_SCALE_BASE:mag):mag; + Debug( 3, "Scaling by %d, zooming by %d = magnifying by %d(%d)", scale, zoom, mag, act_mag ); + + int last_mag = (last_scale * last_zoom) / ZM_SCALE_BASE; + int last_act_mag = last_mag > ZM_SCALE_BASE?ZM_SCALE_BASE:last_mag; + Debug( 3, "Last scaling by %d, zooming by %d = magnifying by %d(%d)", last_scale, last_zoom, last_mag, last_act_mag ); + + int base_image_width = image->Width(), base_image_height = image->Height(); + Debug( 3, "Base image width = %d, height = %d", base_image_width, base_image_height ); + + int virt_image_width = (base_image_width * mag) / ZM_SCALE_BASE, virt_image_height = (base_image_height * mag) / ZM_SCALE_BASE; + Debug( 3, "Virtual image width = %d, height = %d", virt_image_width, virt_image_height ); + + int last_virt_image_width = (base_image_width * last_mag) / ZM_SCALE_BASE, last_virt_image_height = (base_image_height * last_mag) / ZM_SCALE_BASE; + Debug( 3, "Last virtual image width = %d, height = %d", last_virt_image_width, last_virt_image_height ); + + int act_image_width = (base_image_width * act_mag ) / ZM_SCALE_BASE, act_image_height = (base_image_height * act_mag ) / ZM_SCALE_BASE; + Debug( 3, "Actual image width = %d, height = %d", act_image_width, act_image_height ); + + int last_act_image_width = (base_image_width * last_act_mag ) / ZM_SCALE_BASE, last_act_image_height = (base_image_height * last_act_mag ) / ZM_SCALE_BASE; + Debug( 3, "Last actual image width = %d, height = %d", last_act_image_width, last_act_image_height ); + + int disp_image_width = (image->Width() * scale) / ZM_SCALE_BASE, disp_image_height = (image->Height() * scale) / ZM_SCALE_BASE; + Debug( 3, "Display image width = %d, height = %d", disp_image_width, disp_image_height ); + + int last_disp_image_width = (image->Width() * last_scale) / ZM_SCALE_BASE, last_disp_image_height = (image->Height() * last_scale) / ZM_SCALE_BASE; + Debug( 3, "Last display image width = %d, height = %d", last_disp_image_width, last_disp_image_height ); + + int send_image_width = (disp_image_width * act_mag ) / mag, send_image_height = (disp_image_height * act_mag ) / mag; + Debug( 3, "Send image width = %d, height = %d", send_image_width, send_image_height ); + + int last_send_image_width = (last_disp_image_width * last_act_mag ) / last_mag, last_send_image_height = (last_disp_image_height * last_act_mag ) / last_mag; + Debug( 3, "Last send image width = %d, height = %d", last_send_image_width, last_send_image_height ); + + if ( mag != ZM_SCALE_BASE ) + { + if ( act_mag != ZM_SCALE_BASE ) + { + Debug( 3, "Magnifying by %d", mag ); + if ( !image_copied ) + { + static Image copy_image; + copy_image.Assign( *image ); + image = ©_image; + image_copied = true; + } + image->Scale( mag ); + } + } + + Debug( 3, "Real image width = %d, height = %d", image->Width(), image->Height() ); + + if ( disp_image_width < virt_image_width || disp_image_height < virt_image_height ) + { + static Box last_crop; + + if ( mag != last_mag || x != last_x || y != last_y ) + { + Debug( 3, "Got click at %d,%d x %d", x, y, mag ); + + //if ( !last_mag ) + //last_mag = mag; + + if ( !(last_disp_image_width < last_virt_image_width || last_disp_image_height < last_virt_image_height) ) + last_crop = Box(); + + Debug( 3, "Recalculating crop" ); + // Recalculate crop parameters, as %ges + int click_x = (last_crop.LoX() * 100 ) / last_act_image_width; // Initial crop offset from last image + click_x += ( x * 100 ) / last_virt_image_width; + int click_y = (last_crop.LoY() * 100 ) / last_act_image_height; // Initial crop offset from last image + click_y += ( y * 100 ) / last_virt_image_height; + Debug( 3, "Got adjusted click at %d%%,%d%%", click_x, click_y ); + + // Convert the click locations to the current image pixels + click_x = ( click_x * act_image_width ) / 100; + click_y = ( click_y * act_image_height ) / 100; + Debug( 3, "Got readjusted click at %d,%d", click_x, click_y ); + + int lo_x = click_x - (send_image_width/2); + if ( lo_x < 0 ) + lo_x = 0; + int hi_x = lo_x + (send_image_width-1); + if ( hi_x >= act_image_width ) + { + hi_x = act_image_width - 1; + lo_x = hi_x - (send_image_width - 1); + } + + int lo_y = click_y - (send_image_height/2); + if ( lo_y < 0 ) + lo_y = 0; + int hi_y = lo_y + (send_image_height-1); + if ( hi_y >= act_image_height ) + { + hi_y = act_image_height - 1; + lo_y = hi_y - (send_image_height - 1); + } + last_crop = Box( lo_x, lo_y, hi_x, hi_y ); + } + Debug( 3, "Cropping to %d,%d -> %d,%d", last_crop.LoX(), last_crop.LoY(), last_crop.HiX(), last_crop.HiY() ); + if ( !image_copied ) + { + static Image copy_image; + copy_image.Assign( *image ); + image = ©_image; + image_copied = true; + } + image->Crop( last_crop ); + } + last_scale = scale; + last_zoom = zoom; + last_x = x; + last_y = y; + + return( image ); } bool StreamBase::sendTextFrame( const char *frame_text ) { - Debug( 2, "Sending text frame '%s'", frame_text ); + Debug( 2, "Sending text frame '%s'", frame_text ); - Image image( monitor->Width(), monitor->Height(), monitor->Colours(), monitor->SubpixelOrder() ); - image.Annotate( frame_text, image.centreCoord( frame_text ) ); + Image image( monitor->Width(), monitor->Height(), monitor->Colours(), monitor->SubpixelOrder() ); + image.Annotate( frame_text, image.centreCoord( frame_text ) ); - if ( scale != 100 ) - { - image.Scale( scale ); - } + if ( scale != 100 ) + { + image.Scale( scale ); + } #if HAVE_LIBAVCODEC - if ( type == STREAM_MPEG ) + if ( type == STREAM_MPEG ) + { + if ( !vid_stream ) { - if ( !vid_stream ) - { - vid_stream = new VideoStream( "pipe:", format, bitrate, effective_fps, image.Colours(), image.SubpixelOrder(), image.Width(), image.Height() ); - fprintf( stdout, "Content-type: %s\r\n\r\n", vid_stream->MimeType() ); - vid_stream->OpenStream(); - } - /* double pts = */ vid_stream->EncodeFrame( image.Buffer(), image.Size() ); + vid_stream = new VideoStream( "pipe:", format, bitrate, effective_fps, image.Colours(), image.SubpixelOrder(), image.Width(), image.Height() ); + fprintf( stdout, "Content-type: %s\r\n\r\n", vid_stream->MimeType() ); + vid_stream->OpenStream(); } - else + /* double pts = */ vid_stream->EncodeFrame( image.Buffer(), image.Size() ); + } + else #endif // HAVE_LIBAVCODEC + { + static unsigned char buffer[ZM_MAX_IMAGE_SIZE]; + int n_bytes = 0; + + image.EncodeJpeg( buffer, &n_bytes ); + + fprintf( stdout, "--ZoneMinderFrame\r\n" ); + fprintf( stdout, "Content-Length: %d\r\n", n_bytes ); + fprintf( stdout, "Content-Type: image/jpeg\r\n\r\n" ); + if ( fwrite( buffer, n_bytes, 1, stdout ) != 1 ) { - static unsigned char buffer[ZM_MAX_IMAGE_SIZE]; - int n_bytes = 0; - - image.EncodeJpeg( buffer, &n_bytes ); - - fprintf( stdout, "--ZoneMinderFrame\r\n" ); - fprintf( stdout, "Content-Length: %d\r\n", n_bytes ); - fprintf( stdout, "Content-Type: image/jpeg\r\n\r\n" ); - if ( fwrite( buffer, n_bytes, 1, stdout ) != 1 ) - { - Error( "Unable to send stream text frame: %s", strerror(errno) ); - return( false ); - } - fprintf( stdout, "\r\n\r\n" ); - fflush( stdout ); + Error( "Unable to send stream text frame: %s", strerror(errno) ); + return( false ); } - last_frame_sent = TV_2_FLOAT( now ); - return( true ); + fprintf( stdout, "\r\n\r\n" ); + fflush( stdout ); + } + last_frame_sent = TV_2_FLOAT( now ); + return( true ); } void StreamBase::openComms() { - if ( connkey > 0 ) + if ( connkey > 0 ) + { + + snprintf( sock_path_lock, sizeof(sock_path_lock), "%s/zms-%06d.lock", config.path_socks, connkey); + + lock_fd = open(sock_path_lock, O_CREAT|O_WRONLY, S_IRUSR | S_IWUSR); + if ( lock_fd <= 0 ) { - - snprintf( sock_path_lock, sizeof(sock_path_lock), "%s/zms-%06d.lock", config.path_socks, connkey); - - lock_fd = open(sock_path_lock, O_CREAT|O_WRONLY, S_IRUSR | S_IWUSR); - if ( lock_fd <= 0 ) - { - Error("Unable to open sock lock file %s: %s", sock_path_lock, strerror(errno) ); - lock_fd = 0; - } - else if ( flock(lock_fd, LOCK_EX) != 0 ) - { - Error("Unable to lock sock lock file %s: %s", sock_path_lock, strerror(errno) ); - - close(lock_fd); - lock_fd = 0; - } - else - { - Debug( 1, "We have obtained a lock on %s fd: %d", sock_path_lock, lock_fd); - } - - - sd = socket( AF_UNIX, SOCK_DGRAM, 0 ); - if ( sd < 0 ) - { - Fatal( "Can't create socket: %s", strerror(errno) ); - } - - snprintf( loc_sock_path, sizeof(loc_sock_path), "%s/zms-%06ds.sock", config.path_socks, connkey ); - unlink( loc_sock_path ); - - strncpy( loc_addr.sun_path, loc_sock_path, sizeof(loc_addr.sun_path) ); - loc_addr.sun_family = AF_UNIX; - if ( bind( sd, (struct sockaddr *)&loc_addr, strlen(loc_addr.sun_path)+sizeof(loc_addr.sun_family)) < 0 ) - { - Fatal( "Can't bind: %s", strerror(errno) ); - } - - snprintf( rem_sock_path, sizeof(rem_sock_path), "%s/zms-%06dw.sock", config.path_socks, connkey ); - strncpy( rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path) ); - rem_addr.sun_family = AF_UNIX; + Error("Unable to open sock lock file %s: %s", sock_path_lock, strerror(errno) ); + lock_fd = 0; } + else if ( flock(lock_fd, LOCK_EX) != 0 ) + { + Error("Unable to lock sock lock file %s: %s", sock_path_lock, strerror(errno) ); + + close(lock_fd); + lock_fd = 0; + } + else + { + Debug( 1, "We have obtained a lock on %s fd: %d", sock_path_lock, lock_fd); + } + + + sd = socket( AF_UNIX, SOCK_DGRAM, 0 ); + if ( sd < 0 ) + { + Fatal( "Can't create socket: %s", strerror(errno) ); + } + + snprintf( loc_sock_path, sizeof(loc_sock_path), "%s/zms-%06ds.sock", config.path_socks, connkey ); + unlink( loc_sock_path ); + + strncpy( loc_addr.sun_path, loc_sock_path, sizeof(loc_addr.sun_path) ); + loc_addr.sun_family = AF_UNIX; + if ( bind( sd, (struct sockaddr *)&loc_addr, strlen(loc_addr.sun_path)+sizeof(loc_addr.sun_family)) < 0 ) + { + Fatal( "Can't bind: %s", strerror(errno) ); + } + + snprintf( rem_sock_path, sizeof(rem_sock_path), "%s/zms-%06dw.sock", config.path_socks, connkey ); + strncpy( rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path) ); + rem_addr.sun_family = AF_UNIX; + } } void StreamBase::closeComms() { - if ( connkey > 0 ) + if ( connkey > 0 ) + { + if ( sd >= 0 ) { - if ( sd >= 0 ) - { - close( sd ); - sd = -1; - } - if ( loc_sock_path[0] ) - { - unlink( loc_sock_path ); - } - if (lock_fd > 0) - { - close(lock_fd); //close it rather than unlock it incase it got deleted. - unlink(sock_path_lock); - } + close( sd ); + sd = -1; } + if ( loc_sock_path[0] ) + { + unlink( loc_sock_path ); + } + if (lock_fd > 0) + { + close(lock_fd); //close it rather than unlock it incase it got deleted. + unlink(sock_path_lock); + } + } } diff --git a/src/zm_stream.h b/src/zm_stream.h index 4f6442725..c7df53d16 100644 --- a/src/zm_stream.h +++ b/src/zm_stream.h @@ -33,149 +33,149 @@ class Monitor; class StreamBase { public: - typedef enum { STREAM_JPEG, STREAM_RAW, STREAM_ZIP, STREAM_SINGLE, STREAM_MPEG } StreamType; + typedef enum { STREAM_JPEG, STREAM_RAW, STREAM_ZIP, STREAM_SINGLE, STREAM_MPEG } StreamType; protected: - static const int MAX_STREAM_DELAY = 5; // Seconds + static const int MAX_STREAM_DELAY = 5; // Seconds - static const StreamType DEFAULT_TYPE = STREAM_JPEG; - enum { DEFAULT_RATE=ZM_RATE_BASE }; - enum { DEFAULT_SCALE=ZM_SCALE_BASE }; - enum { DEFAULT_ZOOM=ZM_SCALE_BASE }; - enum { DEFAULT_MAXFPS=10 }; - enum { DEFAULT_BITRATE=100000 }; + static const StreamType DEFAULT_TYPE = STREAM_JPEG; + enum { DEFAULT_RATE=ZM_RATE_BASE }; + enum { DEFAULT_SCALE=ZM_SCALE_BASE }; + enum { DEFAULT_ZOOM=ZM_SCALE_BASE }; + enum { DEFAULT_MAXFPS=10 }; + enum { DEFAULT_BITRATE=100000 }; protected: - typedef struct { - int msg_type; - char msg_data[16]; - } CmdMsg; + typedef struct { + int msg_type; + char msg_data[16]; + } CmdMsg; - typedef struct { - int msg_type; - char msg_data[256]; - } DataMsg; + typedef struct { + int msg_type; + char msg_data[256]; + } DataMsg; - typedef enum { MSG_CMD=1, MSG_DATA_WATCH, MSG_DATA_EVENT } MsgType; - typedef enum { CMD_NONE=0, CMD_PAUSE, CMD_PLAY, CMD_STOP, CMD_FASTFWD, CMD_SLOWFWD, CMD_SLOWREV, CMD_FASTREV, CMD_ZOOMIN, CMD_ZOOMOUT, CMD_PAN, CMD_SCALE, CMD_PREV, CMD_NEXT, CMD_SEEK, CMD_VARPLAY, CMD_GET_IMAGE, CMD_QUIT, CMD_QUERY=99 } MsgCommand; + typedef enum { MSG_CMD=1, MSG_DATA_WATCH, MSG_DATA_EVENT } MsgType; + typedef enum { CMD_NONE=0, CMD_PAUSE, CMD_PLAY, CMD_STOP, CMD_FASTFWD, CMD_SLOWFWD, CMD_SLOWREV, CMD_FASTREV, CMD_ZOOMIN, CMD_ZOOMOUT, CMD_PAN, CMD_SCALE, CMD_PREV, CMD_NEXT, CMD_SEEK, CMD_VARPLAY, CMD_GET_IMAGE, CMD_QUIT, CMD_QUERY=99 } MsgCommand; protected: - Monitor *monitor; + Monitor *monitor; - StreamType type; - const char *format; - int replay_rate; - int scale; - int zoom; - double maxfps; - int bitrate; - unsigned short x, y; + StreamType type; + const char *format; + int replay_rate; + int scale; + int zoom; + double maxfps; + int bitrate; + unsigned short x, y; protected: - int connkey; - int sd; - char loc_sock_path[PATH_MAX]; - struct sockaddr_un loc_addr; - char rem_sock_path[PATH_MAX]; - struct sockaddr_un rem_addr; - char sock_path_lock[PATH_MAX]; - int lock_fd; + int connkey; + int sd; + char loc_sock_path[PATH_MAX]; + struct sockaddr_un loc_addr; + char rem_sock_path[PATH_MAX]; + struct sockaddr_un rem_addr; + char sock_path_lock[PATH_MAX]; + int lock_fd; protected: - bool paused; - int step; + bool paused; + int step; - struct timeval now; + struct timeval now; - double base_fps; - double effective_fps; - int frame_mod; + double base_fps; + double effective_fps; + int frame_mod; - double last_frame_sent; - struct timeval last_frame_timestamp; + double last_frame_sent; + struct timeval last_frame_timestamp; -#if HAVE_LIBAVCODEC - VideoStream *vid_stream; -#endif // HAVE_LIBAVCODEC +#if HAVE_LIBAVCODEC + VideoStream *vid_stream; +#endif // HAVE_LIBAVCODEC - CmdMsg msg; + CmdMsg msg; protected: - bool loadMonitor( int monitor_id ); - bool checkInitialised(); - void updateFrameRate( double fps ); - Image *prepareImage( Image *image ); - bool sendTextFrame( const char *text ); - bool checkCommandQueue(); - virtual void processCommand( const CmdMsg *msg )=0; + bool loadMonitor( int monitor_id ); + bool checkInitialised(); + void updateFrameRate( double fps ); + Image *prepareImage( Image *image ); + bool sendTextFrame( const char *text ); + bool checkCommandQueue(); + virtual void processCommand( const CmdMsg *msg )=0; public: - StreamBase() - { - monitor = 0; + StreamBase() + { + monitor = 0; - type = DEFAULT_TYPE; - format = ""; - replay_rate = DEFAULT_RATE; - scale = DEFAULT_SCALE; - zoom = DEFAULT_ZOOM; - maxfps = DEFAULT_MAXFPS; - bitrate = DEFAULT_BITRATE; + type = DEFAULT_TYPE; + format = ""; + replay_rate = DEFAULT_RATE; + scale = DEFAULT_SCALE; + zoom = DEFAULT_ZOOM; + maxfps = DEFAULT_MAXFPS; + bitrate = DEFAULT_BITRATE; - paused = false; - step = 0; - x = 0; - y = 0; + paused = false; + step = 0; + x = 0; + y = 0; - connkey = 0; - sd = -1; - lock_fd = 0; - memset( &loc_sock_path, 0, sizeof(loc_sock_path) ); - memset( &loc_addr, 0, sizeof(loc_addr) ); - memset( &rem_sock_path, 0, sizeof(rem_sock_path) ); - memset( &rem_addr, 0, sizeof(rem_addr) ); + connkey = 0; + sd = -1; + lock_fd = 0; + memset( &loc_sock_path, 0, sizeof(loc_sock_path) ); + memset( &loc_addr, 0, sizeof(loc_addr) ); + memset( &rem_sock_path, 0, sizeof(rem_sock_path) ); + memset( &rem_addr, 0, sizeof(rem_addr) ); - base_fps = 0.0; - effective_fps = 0.0; - frame_mod = 1; + base_fps = 0.0; + effective_fps = 0.0; + frame_mod = 1; -#if HAVE_LIBAVCODEC - vid_stream = 0; -#endif // HAVE_LIBAVCODEC - } - virtual ~StreamBase(); +#if HAVE_LIBAVCODEC + vid_stream = 0; +#endif // HAVE_LIBAVCODEC + } + virtual ~StreamBase(); - void setStreamType( StreamType p_type ) - { - type = p_type; - } - void setStreamFormat( const char *p_format ) - { - format = p_format; - } - void setStreamScale( int p_scale ) - { - scale = p_scale; - } - void setStreamReplayRate( int p_rate ) - { - replay_rate = p_rate; - } - void setStreamMaxFPS( double p_maxfps ) - { - maxfps = p_maxfps; - } - void setStreamBitrate( int p_bitrate ) - { - bitrate = p_bitrate; - } - void setStreamQueue( int p_connkey ) - { - connkey = p_connkey; - } - virtual void openComms(); - virtual void closeComms(); - virtual void runStream()=0; + void setStreamType( StreamType p_type ) + { + type = p_type; + } + void setStreamFormat( const char *p_format ) + { + format = p_format; + } + void setStreamScale( int p_scale ) + { + scale = p_scale; + } + void setStreamReplayRate( int p_rate ) + { + replay_rate = p_rate; + } + void setStreamMaxFPS( double p_maxfps ) + { + maxfps = p_maxfps; + } + void setStreamBitrate( int p_bitrate ) + { + bitrate = p_bitrate; + } + void setStreamQueue( int p_connkey ) + { + connkey = p_connkey; + } + virtual void openComms(); + virtual void closeComms(); + virtual void runStream()=0; }; #endif // ZM_STREAM_H diff --git a/src/zm_thread.cpp b/src/zm_thread.cpp index 09cf0da3f..7d84037d9 100644 --- a/src/zm_thread.cpp +++ b/src/zm_thread.cpp @@ -29,311 +29,310 @@ struct timespec getTimeout( int secs ) { - struct timespec timeout; - struct timeval temp_timeout; - gettimeofday( &temp_timeout, 0 ); - timeout.tv_sec = temp_timeout.tv_sec + secs; - timeout.tv_nsec = temp_timeout.tv_usec*1000; - return( timeout ); + struct timespec timeout; + struct timeval temp_timeout; + gettimeofday( &temp_timeout, 0 ); + timeout.tv_sec = temp_timeout.tv_sec + secs; + timeout.tv_nsec = temp_timeout.tv_usec*1000; + return( timeout ); } struct timespec getTimeout( double secs ) { - struct timespec timeout; - struct timeval temp_timeout; - gettimeofday( &temp_timeout, 0 ); - timeout.tv_sec = temp_timeout.tv_sec + int(secs); - timeout.tv_nsec = temp_timeout.tv_usec += (long int)(1000000000.0*(secs-int(secs))); - if ( timeout.tv_nsec > 1000000000 ) - { - timeout.tv_sec += 1; - timeout.tv_nsec -= 1000000000; - } - return( timeout ); + struct timespec timeout; + struct timeval temp_timeout; + gettimeofday( &temp_timeout, 0 ); + timeout.tv_sec = temp_timeout.tv_sec + int(secs); + timeout.tv_nsec = temp_timeout.tv_usec += (long int)(1000000000.0*(secs-int(secs))); + if ( timeout.tv_nsec > 1000000000 ) + { + timeout.tv_sec += 1; + timeout.tv_nsec -= 1000000000; + } + return( timeout ); } Mutex::Mutex() { - if ( pthread_mutex_init( &mMutex, NULL ) < 0 ) - throw ThreadException( stringtf( "Unable to create pthread mutex: %s", strerror(errno) ) ); + if ( pthread_mutex_init( &mMutex, NULL ) < 0 ) + throw ThreadException( stringtf( "Unable to create pthread mutex: %s", strerror(errno) ) ); } Mutex::~Mutex() { - if ( locked() ) - Warning( "Destroying mutex when locked" ); - if ( pthread_mutex_destroy( &mMutex ) < 0 ) - throw ThreadException( stringtf( "Unable to destroy pthread mutex: %s", strerror(errno) ) ); + if ( locked() ) + Warning( "Destroying mutex when locked" ); + if ( pthread_mutex_destroy( &mMutex ) < 0 ) + throw ThreadException( stringtf( "Unable to destroy pthread mutex: %s", strerror(errno) ) ); } void Mutex::lock() { - if ( pthread_mutex_lock( &mMutex ) < 0 ) - throw ThreadException( stringtf( "Unable to lock pthread mutex: %s", strerror(errno) ) ); + if ( pthread_mutex_lock( &mMutex ) < 0 ) + throw ThreadException( stringtf( "Unable to lock pthread mutex: %s", strerror(errno) ) ); } void Mutex::lock( int secs ) { - struct timespec timeout = getTimeout( secs ); - if ( pthread_mutex_timedlock( &mMutex, &timeout ) < 0 ) - throw ThreadException( stringtf( "Unable to timedlock pthread mutex: %s", strerror(errno) ) ); + struct timespec timeout = getTimeout( secs ); + if ( pthread_mutex_timedlock( &mMutex, &timeout ) < 0 ) + throw ThreadException( stringtf( "Unable to timedlock pthread mutex: %s", strerror(errno) ) ); } void Mutex::lock( double secs ) { - struct timespec timeout = getTimeout( secs ); - if ( pthread_mutex_timedlock( &mMutex, &timeout ) < 0 ) - throw ThreadException( stringtf( "Unable to timedlock pthread mutex: %s", strerror(errno) ) ); + struct timespec timeout = getTimeout( secs ); + if ( pthread_mutex_timedlock( &mMutex, &timeout ) < 0 ) + throw ThreadException( stringtf( "Unable to timedlock pthread mutex: %s", strerror(errno) ) ); } void Mutex::unlock() { - if ( pthread_mutex_unlock( &mMutex ) < 0 ) - throw ThreadException( stringtf( "Unable to unlock pthread mutex: %s", strerror(errno) ) ); + if ( pthread_mutex_unlock( &mMutex ) < 0 ) + throw ThreadException( stringtf( "Unable to unlock pthread mutex: %s", strerror(errno) ) ); } bool Mutex::locked() { - int state = pthread_mutex_trylock( &mMutex ); - if ( state != 0 && state != EBUSY ) - throw ThreadException( stringtf( "Unable to trylock pthread mutex: %s", strerror(errno) ) ); - if ( state != EBUSY ) - unlock(); - return( state == EBUSY ); + int state = pthread_mutex_trylock( &mMutex ); + if ( state != 0 && state != EBUSY ) + throw ThreadException( stringtf( "Unable to trylock pthread mutex: %s", strerror(errno) ) ); + if ( state != EBUSY ) + unlock(); + return( state == EBUSY ); } Condition::Condition( Mutex &mutex ) : mMutex( mutex ) { - if ( pthread_cond_init( &mCondition, NULL ) < 0 ) - throw ThreadException( stringtf( "Unable to create pthread condition: %s", strerror(errno) ) ); + if ( pthread_cond_init( &mCondition, NULL ) < 0 ) + throw ThreadException( stringtf( "Unable to create pthread condition: %s", strerror(errno) ) ); } Condition::~Condition() { - if ( pthread_cond_destroy( &mCondition ) < 0 ) - throw ThreadException( stringtf( "Unable to destroy pthread condition: %s", strerror(errno) ) ); + if ( pthread_cond_destroy( &mCondition ) < 0 ) + throw ThreadException( stringtf( "Unable to destroy pthread condition: %s", strerror(errno) ) ); } void Condition::wait() { - // Locking done outside of this function - if ( pthread_cond_wait( &mCondition, mMutex.getMutex() ) < 0 ) - throw ThreadException( stringtf( "Unable to wait pthread condition: %s", strerror(errno) ) ); + // Locking done outside of this function + if ( pthread_cond_wait( &mCondition, mMutex.getMutex() ) < 0 ) + throw ThreadException( stringtf( "Unable to wait pthread condition: %s", strerror(errno) ) ); } bool Condition::wait( int secs ) { - // Locking done outside of this function - Debug( 8, "Waiting for %d seconds", secs ); - struct timespec timeout = getTimeout( secs ); - if ( pthread_cond_timedwait( &mCondition, mMutex.getMutex(), &timeout ) < 0 && errno != ETIMEDOUT ) - throw ThreadException( stringtf( "Unable to timedwait pthread condition: %s", strerror(errno) ) ); - return( errno != ETIMEDOUT ); + // Locking done outside of this function + Debug( 8, "Waiting for %d seconds", secs ); + struct timespec timeout = getTimeout( secs ); + if ( pthread_cond_timedwait( &mCondition, mMutex.getMutex(), &timeout ) < 0 && errno != ETIMEDOUT ) + throw ThreadException( stringtf( "Unable to timedwait pthread condition: %s", strerror(errno) ) ); + return( errno != ETIMEDOUT ); } bool Condition::wait( double secs ) { - // Locking done outside of this function - struct timespec timeout = getTimeout( secs ); - if ( pthread_cond_timedwait( &mCondition, mMutex.getMutex(), &timeout ) < 0 && errno != ETIMEDOUT ) - throw ThreadException( stringtf( "Unable to timedwait pthread condition: %s", strerror(errno) ) ); - return( errno != ETIMEDOUT ); + // Locking done outside of this function + struct timespec timeout = getTimeout( secs ); + if ( pthread_cond_timedwait( &mCondition, mMutex.getMutex(), &timeout ) < 0 && errno != ETIMEDOUT ) + throw ThreadException( stringtf( "Unable to timedwait pthread condition: %s", strerror(errno) ) ); + return( errno != ETIMEDOUT ); } void Condition::signal() { - if ( pthread_cond_signal( &mCondition ) < 0 ) - throw ThreadException( stringtf( "Unable to signal pthread condition: %s", strerror(errno) ) ); + if ( pthread_cond_signal( &mCondition ) < 0 ) + throw ThreadException( stringtf( "Unable to signal pthread condition: %s", strerror(errno) ) ); } void Condition::broadcast() { - if ( pthread_cond_broadcast( &mCondition ) < 0 ) - throw ThreadException( stringtf( "Unable to broadcast pthread condition: %s", strerror(errno) ) ); + if ( pthread_cond_broadcast( &mCondition ) < 0 ) + throw ThreadException( stringtf( "Unable to broadcast pthread condition: %s", strerror(errno) ) ); } template const T ThreadData::getValue() const { - mMutex.lock(); - const T valueCopy = mValue; - mMutex.unlock(); - return( valueCopy ); + mMutex.lock(); + const T valueCopy = mValue; + mMutex.unlock(); + return( valueCopy ); } template T ThreadData::setValue( const T value ) { - mMutex.lock(); - const T valueCopy = mValue = value; - mMutex.unlock(); - return( valueCopy ); + mMutex.lock(); + const T valueCopy = mValue = value; + mMutex.unlock(); + return( valueCopy ); } template const T ThreadData::getUpdatedValue() const { - Debug( 8, "Waiting for value update, %p", this ); - mMutex.lock(); - mChanged = false; - //do { - mCondition.wait(); - //} while ( !mChanged ); - const T valueCopy = mValue; - mMutex.unlock(); - Debug( 9, "Got value update, %p", this ); - return( valueCopy ); + Debug( 8, "Waiting for value update, %p", this ); + mMutex.lock(); + mChanged = false; + //do { + mCondition.wait(); + //} while ( !mChanged ); + const T valueCopy = mValue; + mMutex.unlock(); + Debug( 9, "Got value update, %p", this ); + return( valueCopy ); } template const T ThreadData::getUpdatedValue( double secs ) const { - Debug( 8, "Waiting for value update, %.2f secs, %p", secs, this ); - mMutex.lock(); - mChanged = false; - //do { - mCondition.wait( secs ); - //} while ( !mChanged ); - const T valueCopy = mValue; - mMutex.unlock(); - Debug( 9, "Got value update, %p", this ); - return( valueCopy ); + Debug( 8, "Waiting for value update, %.2f secs, %p", secs, this ); + mMutex.lock(); + mChanged = false; + //do { + mCondition.wait( secs ); + //} while ( !mChanged ); + const T valueCopy = mValue; + mMutex.unlock(); + Debug( 9, "Got value update, %p", this ); + return( valueCopy ); } template const T ThreadData::getUpdatedValue( int secs ) const { - Debug( 8, "Waiting for value update, %d secs, %p", secs, this ); - mMutex.lock(); - mChanged = false; - //do { - mCondition.wait( secs ); - //} while ( !mChanged ); - const T valueCopy = mValue; - mMutex.unlock(); - Debug( 9, "Got value update, %p", this ); - return( valueCopy ); + Debug( 8, "Waiting for value update, %d secs, %p", secs, this ); + mMutex.lock(); + mChanged = false; + //do { + mCondition.wait( secs ); + //} while ( !mChanged ); + const T valueCopy = mValue; + mMutex.unlock(); + Debug( 9, "Got value update, %p", this ); + return( valueCopy ); } template void ThreadData::updateValueSignal( const T value ) { - Debug( 8, "Updating value with signal, %p", this ); - mMutex.lock(); - mValue = value; - mChanged = true; - mCondition.signal(); - mMutex.unlock(); - Debug( 9, "Updated value, %p", this ); + Debug( 8, "Updating value with signal, %p", this ); + mMutex.lock(); + mValue = value; + mChanged = true; + mCondition.signal(); + mMutex.unlock(); + Debug( 9, "Updated value, %p", this ); } template void ThreadData::updateValueBroadcast( const T value ) { - Debug( 8, "Updating value with broadcast, %p", this ); - mMutex.lock(); - mValue = value; - mChanged = true; - mCondition.broadcast(); - mMutex.unlock(); - Debug( 9, "Updated value, %p", this ); + Debug( 8, "Updating value with broadcast, %p", this ); + mMutex.lock(); + mValue = value; + mChanged = true; + mCondition.broadcast(); + mMutex.unlock(); + Debug( 9, "Updated value, %p", this ); } Thread::Thread() : - mThreadCondition( mThreadMutex ), - mPid( -1 ), - mStarted( false ), - mRunning( false ) + mThreadCondition( mThreadMutex ), + mPid( -1 ), + mStarted( false ), + mRunning( false ) { - Debug( 1, "Creating thread" ); + Debug( 1, "Creating thread" ); } Thread::~Thread() { - Debug( 1, "Destroying thread %d", mPid ); - if ( mStarted ) - join(); + Debug( 1, "Destroying thread %d", mPid ); + if ( mStarted ) + join(); } void *Thread::mThreadFunc( void *arg ) { - Debug( 2, "Invoking thread" ); + Debug( 2, "Invoking thread" ); - Thread *thisPtr = (Thread *)arg; - void *status = 0; - try - { - thisPtr->mThreadMutex.lock(); - thisPtr->mPid = thisPtr->id(); - thisPtr->mThreadCondition.signal(); - thisPtr->mThreadMutex.unlock(); - thisPtr->mRunning = true; - int run=(thisPtr->run()); - status = (void *)&run; - thisPtr->mRunning = false; - Debug( 2, "Exiting thread, status %p", status ); - } - catch ( const ThreadException &e ) - { - Error( "%s", e.getMessage().c_str() ); - thisPtr->mRunning = false; - status = (void *)-1; - Debug( 2, "Exiting thread after exception, status %p", status ); - } - return( status ); + Thread *thisPtr = (Thread *)arg; + thisPtr->status = 0; + try + { + thisPtr->mThreadMutex.lock(); + thisPtr->mPid = thisPtr->id(); + thisPtr->mThreadCondition.signal(); + thisPtr->mThreadMutex.unlock(); + thisPtr->mRunning = true; + thisPtr->status = thisPtr->run(); + thisPtr->mRunning = false; + Debug( 2, "Exiting thread, status %p", (void *)&(thisPtr->status) ); + return (void *)&(thisPtr->status); + } + catch ( const ThreadException &e ) + { + Error( "%s", e.getMessage().c_str() ); + thisPtr->mRunning = false; + Debug( 2, "Exiting thread after exception, status %p", (void *)-1 ); + return (void *)-1; + } } void Thread::start() { - Debug( 1, "Starting thread" ); - if ( isThread() ) - throw ThreadException( "Can't self start thread" ); - mThreadMutex.lock(); - if ( !mStarted ) - { - pthread_attr_t threadAttrs; - pthread_attr_init( &threadAttrs ); - pthread_attr_setscope( &threadAttrs, PTHREAD_SCOPE_SYSTEM ); + Debug( 1, "Starting thread" ); + if ( isThread() ) + throw ThreadException( "Can't self start thread" ); + mThreadMutex.lock(); + if ( !mStarted ) + { + pthread_attr_t threadAttrs; + pthread_attr_init( &threadAttrs ); + pthread_attr_setscope( &threadAttrs, PTHREAD_SCOPE_SYSTEM ); - mStarted = true; - if ( pthread_create( &mThread, &threadAttrs, mThreadFunc, this ) < 0 ) - throw ThreadException( stringtf( "Can't create thread: %s", strerror(errno) ) ); - pthread_attr_destroy( &threadAttrs ); - } - else - { - Error( "Attempt to start already running thread %d", mPid ); - } - mThreadCondition.wait(); - mThreadMutex.unlock(); - Debug( 1, "Started thread %d", mPid ); + mStarted = true; + if ( pthread_create( &mThread, &threadAttrs, mThreadFunc, this ) < 0 ) + throw ThreadException( stringtf( "Can't create thread: %s", strerror(errno) ) ); + pthread_attr_destroy( &threadAttrs ); + } + else + { + Error( "Attempt to start already running thread %d", mPid ); + } + mThreadCondition.wait(); + mThreadMutex.unlock(); + Debug( 1, "Started thread %d", mPid ); } void Thread::join() { - Debug( 1, "Joining thread %d", mPid ); - if ( isThread() ) - throw ThreadException( "Can't self join thread" ); - mThreadMutex.lock(); - if ( mPid >= 0 ) + Debug( 1, "Joining thread %d", mPid ); + if ( isThread() ) + throw ThreadException( "Can't self join thread" ); + mThreadMutex.lock(); + if ( mPid >= 0 ) + { + if ( mStarted ) { - if ( mStarted ) - { - void *threadStatus = 0; - if ( pthread_join( mThread, &threadStatus ) < 0 ) - throw ThreadException( stringtf( "Can't join sender thread: %s", strerror(errno) ) ); - mStarted = false; - Debug( 1, "Thread %d exited, status %p", mPid, threadStatus ); - } - else - { - Warning( "Attempt to join already finished thread %d", mPid ); - } + void *threadStatus = 0; + if ( pthread_join( mThread, &threadStatus ) < 0 ) + throw ThreadException( stringtf( "Can't join sender thread: %s", strerror(errno) ) ); + mStarted = false; + Debug( 1, "Thread %d exited, status %p", mPid, threadStatus ); } else { - Warning( "Attempt to join non-started thread %d", mPid ); + Warning( "Attempt to join already finished thread %d", mPid ); } - mThreadMutex.unlock(); - Debug( 1, "Joined thread %d", mPid ); + } + else + { + Warning( "Attempt to join non-started thread %d", mPid ); + } + mThreadMutex.unlock(); + Debug( 1, "Joined thread %d", mPid ); } void Thread::kill( int signal ) { - pthread_kill( mThread, signal ); + pthread_kill( mThread, signal ); } // Some explicit template instantiations diff --git a/src/zm_thread.h b/src/zm_thread.h index 615bec6aa..15c13bb17 100644 --- a/src/zm_thread.h +++ b/src/zm_thread.h @@ -36,27 +36,27 @@ class ThreadException : public Exception { private: #ifndef SOLARIS -pid_t pid() { + pid_t pid() { pid_t tid; #ifdef __FreeBSD__ long lwpid; thr_self(&lwpid); tid = lwpid; #else - #ifdef __FreeBSD_kernel__ - if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id - # else - tid=syscall(SYS_gettid); - #endif + #ifdef __FreeBSD_kernel__ + if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id + # else + tid=syscall(SYS_gettid); + #endif #endif return tid; -} + } #else -pthread_t pid() { return( pthread_self() ); } + pthread_t pid() { return( pthread_self() ); } #endif public: - ThreadException( const std::string &message ) : Exception( stringtf( "(%d) "+message, (long int)pid() ) ) { - } + ThreadException( const std::string &message ) : Exception( stringtf( "(%d) "+message, (long int)pid() ) ) { + } }; class Mutex @@ -64,214 +64,215 @@ class Mutex friend class Condition; private: - pthread_mutex_t mMutex; + pthread_mutex_t mMutex; public: - Mutex(); - ~Mutex(); + Mutex(); + ~Mutex(); private: - pthread_mutex_t *getMutex() - { - return( &mMutex ); - } + pthread_mutex_t *getMutex() + { + return( &mMutex ); + } public: - void lock(); - void lock( int secs ); - void lock( double secs ); - void unlock(); - bool locked(); + void lock(); + void lock( int secs ); + void lock( double secs ); + void unlock(); + bool locked(); }; class ScopedMutex { private: - Mutex &mMutex; + Mutex &mMutex; public: - ScopedMutex( Mutex &mutex ) : mMutex( mutex ) - { - mMutex.lock(); - } - ~ScopedMutex() - { - mMutex.unlock(); - } + ScopedMutex( Mutex &mutex ) : mMutex( mutex ) + { + mMutex.lock(); + } + ~ScopedMutex() + { + mMutex.unlock(); + } private: - ScopedMutex( const ScopedMutex & ); + ScopedMutex( const ScopedMutex & ); }; class Condition { private: - Mutex &mMutex; - pthread_cond_t mCondition; + Mutex &mMutex; + pthread_cond_t mCondition; public: - Condition( Mutex &mutex ); - ~Condition(); + Condition( Mutex &mutex ); + ~Condition(); - void wait(); - bool wait( int secs ); - bool wait( double secs ); - void signal(); - void broadcast(); + void wait(); + bool wait( int secs ); + bool wait( double secs ); + void signal(); + void broadcast(); }; class Semaphore : public Condition { private: - Mutex mMutex; + Mutex mMutex; public: - Semaphore() : Condition( mMutex ) - { - } + Semaphore() : Condition( mMutex ) + { + } - void wait() - { - mMutex.lock(); - Condition::wait(); - mMutex.unlock(); - } - bool wait( int secs ) - { - mMutex.lock(); - bool result = Condition::wait( secs ); - mMutex.unlock(); - return( result ); - } - bool wait( double secs ) - { - mMutex.lock(); - bool result = Condition::wait( secs ); - mMutex.unlock(); - return( result ); - } - void signal() - { - mMutex.lock(); - Condition::signal(); - mMutex.unlock(); - } - void broadcast() - { - mMutex.lock(); - Condition::broadcast(); - mMutex.unlock(); - } + void wait() + { + mMutex.lock(); + Condition::wait(); + mMutex.unlock(); + } + bool wait( int secs ) + { + mMutex.lock(); + bool result = Condition::wait( secs ); + mMutex.unlock(); + return( result ); + } + bool wait( double secs ) + { + mMutex.lock(); + bool result = Condition::wait( secs ); + mMutex.unlock(); + return( result ); + } + void signal() + { + mMutex.lock(); + Condition::signal(); + mMutex.unlock(); + } + void broadcast() + { + mMutex.lock(); + Condition::broadcast(); + mMutex.unlock(); + } }; template class ThreadData { private: - T mValue; - mutable bool mChanged; - mutable Mutex mMutex; - mutable Condition mCondition; + T mValue; + mutable bool mChanged; + mutable Mutex mMutex; + mutable Condition mCondition; public: - __attribute__((used)) ThreadData() : mCondition( mMutex ) - { - } - __attribute__((used)) ThreadData( T value ) : mValue( value ), mCondition( mMutex ) - { - } - //~ThreadData() {} + __attribute__((used)) ThreadData() : mCondition( mMutex ) + { + } + __attribute__((used)) ThreadData( T value ) : mValue( value ), mCondition( mMutex ) + { + } + //~ThreadData() {} - __attribute__((used)) operator T() const - { - return( getValue() ); - } - __attribute__((used)) const T operator=( const T value ) - { - return( setValue( value ) ); - } + __attribute__((used)) operator T() const + { + return( getValue() ); + } + __attribute__((used)) const T operator=( const T value ) + { + return( setValue( value ) ); + } - __attribute__((used)) const T getValueImmediate() const - { - return( mValue ); - } - __attribute__((used)) T setValueImmediate( const T value ) - { - return( mValue = value ); - } - __attribute__((used)) const T getValue() const; - __attribute__((used)) T setValue( const T value ); - __attribute__((used)) const T getUpdatedValue() const; - __attribute__((used)) const T getUpdatedValue( double secs ) const; - __attribute__((used)) const T getUpdatedValue( int secs ) const; - __attribute__((used)) void updateValueSignal( const T value ); - __attribute__((used)) void updateValueBroadcast( const T value ); + __attribute__((used)) const T getValueImmediate() const + { + return( mValue ); + } + __attribute__((used)) T setValueImmediate( const T value ) + { + return( mValue = value ); + } + __attribute__((used)) const T getValue() const; + __attribute__((used)) T setValue( const T value ); + __attribute__((used)) const T getUpdatedValue() const; + __attribute__((used)) const T getUpdatedValue( double secs ) const; + __attribute__((used)) const T getUpdatedValue( int secs ) const; + __attribute__((used)) void updateValueSignal( const T value ); + __attribute__((used)) void updateValueBroadcast( const T value ); }; class Thread { public: - typedef void *(*ThreadFunc)( void * ); + typedef void *(*ThreadFunc)( void * ); protected: - pthread_t mThread; + pthread_t mThread; - Mutex mThreadMutex; - Condition mThreadCondition; + Mutex mThreadMutex; + Condition mThreadCondition; #ifndef SOLARIS - pid_t mPid; + pid_t mPid; #else - pthread_t mPid; + pthread_t mPid; #endif - bool mStarted; - bool mRunning; + bool mStarted; + bool mRunning; + int status; // Used in various funcions to get around return a local variable protected: - Thread(); - virtual ~Thread(); + Thread(); + virtual ~Thread(); #ifndef SOLARIS - pid_t id() const - { - pid_t tid; + pid_t id() const + { + pid_t tid; #ifdef __FreeBSD__ - long lwpid; - thr_self(&lwpid); - tid = lwpid; + long lwpid; + thr_self(&lwpid); + tid = lwpid; #else - #ifdef __FreeBSD_kernel__ - if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id + #ifdef __FreeBSD_kernel__ + if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id - #else - tid=syscall(SYS_gettid); - #endif + #else + tid=syscall(SYS_gettid); + #endif #endif return tid; - } + } #else - pthread_t id() const - { - return( pthread_self() ); - } + pthread_t id() const + { + return( pthread_self() ); + } #endif - void exit( int status = 0 ) - { - //INFO( "Exiting" ); - pthread_exit( (void *)&status ); - } - static void *mThreadFunc( void *arg ); + void exit( int p_status = 0 ) + { + //INFO( "Exiting" ); + pthread_exit( (void *)&p_status ); + } + static void *mThreadFunc( void *arg ); public: - virtual int run() = 0; + virtual int run() = 0; - void start(); - void join(); - void kill( int signal ); - bool isThread() - { - return( mPid > -1 && pthread_equal( pthread_self(), mThread ) ); - } - bool isStarted() const { return( mStarted ); } - bool isRunning() const { return( mRunning ); } + void start(); + void join(); + void kill( int signal ); + bool isThread() + { + return( mPid > -1 && pthread_equal( pthread_self(), mThread ) ); + } + bool isStarted() const { return( mStarted ); } + bool isRunning() const { return( mRunning ); } }; #endif // ZM_THREAD_H diff --git a/src/zm_time.h b/src/zm_time.h index 646133feb..df79e7fff 100644 --- a/src/zm_time.h +++ b/src/zm_time.h @@ -29,48 +29,48 @@ struct DeltaTimeval { - bool positive; - unsigned long delta; - unsigned long sec; - unsigned long fsec; - unsigned long prec; + bool positive; + unsigned long delta; + unsigned long sec; + unsigned long fsec; + unsigned long prec; }; -#define DT_GRAN_1000000 1000000 -#define DT_PREC_6 DT_GRAN_1000000 -#define DT_GRAN_100000 100000 -#define DT_PREC_5 DT_GRAN_100000 -#define DT_GRAN_10000 10000 -#define DT_PREC_4 DT_GRAN_10000 -#define DT_GRAN_1000 1000 -#define DT_PREC_3 DT_GRAN_1000 -#define DT_GRAN_100 100 -#define DT_PREC_2 DT_GRAN_100 -#define DT_GRAN_10 10 -#define DT_PREC_1 DT_GRAN_10 +#define DT_GRAN_1000000 1000000 +#define DT_PREC_6 DT_GRAN_1000000 +#define DT_GRAN_100000 100000 +#define DT_PREC_5 DT_GRAN_100000 +#define DT_GRAN_10000 10000 +#define DT_PREC_4 DT_GRAN_10000 +#define DT_GRAN_1000 1000 +#define DT_PREC_3 DT_GRAN_1000 +#define DT_GRAN_100 100 +#define DT_PREC_2 DT_GRAN_100 +#define DT_GRAN_10 10 +#define DT_PREC_1 DT_GRAN_10 -#define DT_MAXGRAN DT_GRAN_1000000 +#define DT_MAXGRAN DT_GRAN_1000000 // This obviously wouldn't work for massive deltas but as it's mostly // for frames it will only usually be a fraction of a second or so #define DELTA_TIMEVAL( result, time1, time2, precision ) \ { \ - int delta = (((time1).tv_sec-(time2).tv_sec)*(precision))+(((time1).tv_usec-(time2).tv_usec)/(DT_MAXGRAN/(precision))); \ - result.positive = (delta>=0); \ - result.delta = abs(delta); \ - result.sec = result.delta/(precision); \ - result.fsec = result.delta%(precision); \ - result.prec = (precision); \ + int delta = (((time1).tv_sec-(time2).tv_sec)*(precision))+(((time1).tv_usec-(time2).tv_usec)/(DT_MAXGRAN/(precision))); \ + result.positive = (delta>=0); \ + result.delta = abs(delta); \ + result.sec = result.delta/(precision); \ + result.fsec = result.delta%(precision); \ + result.prec = (precision); \ } #define TIMEVAL_INTERVAL( result, time1, time2, precision ) \ { \ - int delta = (((time1).tv_sec-(time2).tv_sec)*(precision))+(((time1).tv_usec-(time2).tv_usec)/(DT_MAXGRAN/(precision))); \ - result.positive = (delta>=0); \ - result.delta = abs(delta); \ - result.sec = result.delta/(precision); \ - result.fsec = result.delta%(precision); \ - result.prec = (precision); \ + int delta = (((time1).tv_sec-(time2).tv_sec)*(precision))+(((time1).tv_usec-(time2).tv_usec)/(DT_MAXGRAN/(precision))); \ + result.positive = (delta>=0); \ + result.delta = abs(delta); \ + result.sec = result.delta/(precision); \ + result.fsec = result.delta%(precision); \ + result.prec = (precision); \ } #define USEC_PER_SEC 1000000 @@ -82,128 +82,128 @@ typedef typeof(tv.tv_usec) ast_suseconds_t; inline int tvDiffUsec( struct timeval first, struct timeval last ) { - return( (last.tv_sec - first.tv_sec) * USEC_PER_SEC) + ((USEC_PER_SEC + last.tv_usec - first.tv_usec) - USEC_PER_SEC ); + return( (last.tv_sec - first.tv_sec) * USEC_PER_SEC) + ((USEC_PER_SEC + last.tv_usec - first.tv_usec) - USEC_PER_SEC ); } inline int tvDiffUsec( struct timeval first ) { - struct timeval now; - gettimeofday( &now, NULL ); - return( tvDiffUsec( first, now ) ); + struct timeval now; + gettimeofday( &now, NULL ); + return( tvDiffUsec( first, now ) ); } inline int tvDiffMsec( struct timeval first, struct timeval last ) { - return( (last.tv_sec - first.tv_sec) * MSEC_PER_SEC) + (((MSEC_PER_SEC + last.tv_usec - first.tv_usec) / MSEC_PER_SEC) - MSEC_PER_SEC ); + return( (last.tv_sec - first.tv_sec) * MSEC_PER_SEC) + (((MSEC_PER_SEC + last.tv_usec - first.tv_usec) / MSEC_PER_SEC) - MSEC_PER_SEC ); } inline int tvDiffMsec( struct timeval first ) { - struct timeval now; - gettimeofday( &now, NULL ); - return( tvDiffMsec( first, now ) ); + struct timeval now; + gettimeofday( &now, NULL ); + return( tvDiffMsec( first, now ) ); } inline double tvDiffSec( struct timeval first, struct timeval last ) { - return( double(last.tv_sec - first.tv_sec) + double(((USEC_PER_SEC + last.tv_usec - first.tv_usec) - USEC_PER_SEC) / (1.0*USEC_PER_SEC) ) ); + return( double(last.tv_sec - first.tv_sec) + double(((USEC_PER_SEC + last.tv_usec - first.tv_usec) - USEC_PER_SEC) / (1.0*USEC_PER_SEC) ) ); } inline double tvDiffSec( struct timeval first ) { - struct timeval now; - gettimeofday( &now, NULL ); - return( tvDiffSec( first, now ) ); + struct timeval now; + gettimeofday( &now, NULL ); + return( tvDiffSec( first, now ) ); } inline struct timeval tvZero() { - struct timeval t = { 0, 0 }; - return( t ); + struct timeval t = { 0, 0 }; + return( t ); } inline int tvIsZero( const struct timeval t ) { - return( t.tv_sec == 0 && t.tv_usec == 0 ); + return( t.tv_sec == 0 && t.tv_usec == 0 ); } inline int tvCmp( struct timeval t1, struct timeval t2 ) { - if ( t1.tv_sec < t2.tv_sec ) - return( -1 ); - if ( t1.tv_sec > t2.tv_sec ) - return( 1 ); - if ( t1.tv_usec < t2.tv_usec ) - return( -1 ); - if ( t1.tv_usec > t2.tv_usec ) - return( 1 ); - return( 0 ); + if ( t1.tv_sec < t2.tv_sec ) + return( -1 ); + if ( t1.tv_sec > t2.tv_sec ) + return( 1 ); + if ( t1.tv_usec < t2.tv_usec ) + return( -1 ); + if ( t1.tv_usec > t2.tv_usec ) + return( 1 ); + return( 0 ); } inline int tvEq( struct timeval t1, struct timeval t2 ) { - return( t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec ); + return( t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec ); } inline struct timeval tvNow( void ) { - struct timeval t; - gettimeofday( &t, NULL ); - return( t ); + struct timeval t; + gettimeofday( &t, NULL ); + return( t ); } inline struct timeval tvCheck( struct timeval &t ) { - if ( t.tv_usec >= USEC_PER_SEC ) - { - Warning( "Timestamp too large %ld.%ld\n", t.tv_sec, (long int) t.tv_usec ); - t.tv_sec += t.tv_usec / USEC_PER_SEC; - t.tv_usec %= USEC_PER_SEC; - } - else if ( t.tv_usec < 0 ) - { - Warning( "Got negative timestamp %ld.%ld\n", t.tv_sec, (long int)t.tv_usec ); - t.tv_usec = 0; - } - return( t ); + if ( t.tv_usec >= USEC_PER_SEC ) + { + Warning( "Timestamp too large %ld.%ld\n", t.tv_sec, (long int) t.tv_usec ); + t.tv_sec += t.tv_usec / USEC_PER_SEC; + t.tv_usec %= USEC_PER_SEC; + } + else if ( t.tv_usec < 0 ) + { + Warning( "Got negative timestamp %ld.%ld\n", t.tv_sec, (long int)t.tv_usec ); + t.tv_usec = 0; + } + return( t ); } // Add t2 to t1 inline struct timeval tvAdd( struct timeval t1, struct timeval t2 ) { - tvCheck(t1); - tvCheck(t2); - t1.tv_sec += t2.tv_sec; - t1.tv_usec += t2.tv_usec; - if ( t1.tv_usec >= USEC_PER_SEC ) - { - t1.tv_sec++; - t1.tv_usec -= USEC_PER_SEC; - } - return( t1 ); + tvCheck(t1); + tvCheck(t2); + t1.tv_sec += t2.tv_sec; + t1.tv_usec += t2.tv_usec; + if ( t1.tv_usec >= USEC_PER_SEC ) + { + t1.tv_sec++; + t1.tv_usec -= USEC_PER_SEC; + } + return( t1 ); } // Subtract t2 from t1 inline struct timeval tvSub( struct timeval t1, struct timeval t2 ) { - tvCheck(t1); - tvCheck(t2); - t1.tv_sec -= t2.tv_sec; - t1.tv_usec -= t2.tv_usec; - if ( t1.tv_usec < 0 ) - { - t1.tv_sec--; - t1.tv_usec += USEC_PER_SEC; - } - return( t1 ) ; + tvCheck(t1); + tvCheck(t2); + t1.tv_sec -= t2.tv_sec; + t1.tv_usec -= t2.tv_usec; + if ( t1.tv_usec < 0 ) + { + t1.tv_sec--; + t1.tv_usec += USEC_PER_SEC; + } + return( t1 ) ; } inline struct timeval tvMake( time_t sec, suseconds_t usec ) { - struct timeval t; - t.tv_sec = sec; - t.tv_usec = usec; - return( t ); + struct timeval t; + t.tv_sec = sec; + t.tv_usec = usec; + return( t ); } #endif // ZM_TIME_H diff --git a/src/zm_timer.cpp b/src/zm_timer.cpp index fbac45435..a067308b7 100644 --- a/src/zm_timer.cpp +++ b/src/zm_timer.cpp @@ -24,96 +24,96 @@ int Timer::TimerThread::mNextTimerId = 0; Timer::TimerThread::TimerThread( Timer &timer, int duration, bool repeat ) : - mTimerId( 0 ), - mTimer( timer ), - mDuration( duration ), - mRepeat( repeat ), - mReset( false ), - mExpiryFlag( true ) + mTimerId( 0 ), + mTimer( timer ), + mDuration( duration ), + mRepeat( repeat ), + mReset( false ), + mExpiryFlag( true ) { - mAccessMutex.lock(); - mTimerId = mNextTimerId++; - Debug( 5, "Creating timer %d for %d seconds%s", mTimerId, mDuration, mRepeat?", repeating":"" ); - mAccessMutex.unlock(); + mAccessMutex.lock(); + mTimerId = mNextTimerId++; + Debug( 5, "Creating timer %d for %d seconds%s", mTimerId, mDuration, mRepeat?", repeating":"" ); + mAccessMutex.unlock(); } Timer::TimerThread::~TimerThread() { - cancel(); + cancel(); } void Timer::TimerThread::cancel() { - mAccessMutex.lock(); - if ( mRunning ) - { - Debug( 4, "Cancelling timer %d", mTimerId ); - mRepeat = false; - mReset = false; - mExpiryFlag.updateValueSignal( false ); - } - mAccessMutex.unlock(); + mAccessMutex.lock(); + if ( mRunning ) + { + Debug( 4, "Cancelling timer %d", mTimerId ); + mRepeat = false; + mReset = false; + mExpiryFlag.updateValueSignal( false ); + } + mAccessMutex.unlock(); } void Timer::TimerThread::reset() { - mAccessMutex.lock(); - if ( mRunning ) - { - Debug( 4, "Resetting timer" ); - mReset = true; - mExpiryFlag.updateValueSignal( false ); - } - else - { - Error( "Attempting to reset expired timer %d", mTimerId ); - } - mAccessMutex.unlock(); + mAccessMutex.lock(); + if ( mRunning ) + { + Debug( 4, "Resetting timer" ); + mReset = true; + mExpiryFlag.updateValueSignal( false ); + } + else + { + Error( "Attempting to reset expired timer %d", mTimerId ); + } + mAccessMutex.unlock(); } int Timer::TimerThread::run() { - Debug( 4, "Starting timer %d for %d seconds", mTimerId, mDuration ); - bool timerExpired = false; - do + Debug( 4, "Starting timer %d for %d seconds", mTimerId, mDuration ); + bool timerExpired = false; + do + { + mAccessMutex.lock(); + mReset = false; + mExpiryFlag.setValue( true ); + mAccessMutex.unlock(); + timerExpired = mExpiryFlag.getUpdatedValue( mDuration ); + mAccessMutex.lock(); + if ( timerExpired ) { - mAccessMutex.lock(); - mReset = false; - mExpiryFlag.setValue( true ); - mAccessMutex.unlock(); - timerExpired = mExpiryFlag.getUpdatedValue( mDuration ); - mAccessMutex.lock(); - if ( timerExpired ) - { - Debug( 4, "Timer %d expired", mTimerId ); - mTimer.expire(); - } - else - { - Debug( 4, "Timer %d %s", mTimerId, mReset?"reset":"cancelled" ); - } - mAccessMutex.unlock(); - } while ( mRepeat || (mReset && !timerExpired) ); - return( timerExpired ); + Debug( 4, "Timer %d expired", mTimerId ); + mTimer.expire(); + } + else + { + Debug( 4, "Timer %d %s", mTimerId, mReset?"reset":"cancelled" ); + } + mAccessMutex.unlock(); + } while ( mRepeat || (mReset && !timerExpired) ); + return( timerExpired ); } Timer::Timer( int timeout, bool repeat ) : mTimerThread( *this, timeout, repeat ) { - mTimerThread.start(); + mTimerThread.start(); } Timer::~Timer() { - //cancel(); + //cancel(); } void Timer::Timer::cancel() { - mTimerThread.cancel(); + mTimerThread.cancel(); } void Timer::Timer::reset() { - mTimerThread.reset(); + mTimerThread.reset(); } diff --git a/src/zm_timer.h b/src/zm_timer.h index 7afe0a647..2213d3cd0 100644 --- a/src/zm_timer.h +++ b/src/zm_timer.h @@ -30,81 +30,81 @@ class Timer { private: - class TimerException : public Exception - { - private: + class TimerException : public Exception + { + private: #ifndef SOLARIS - pid_t pid() { - pid_t tid; + pid_t pid() { + pid_t tid; #ifdef __FreeBSD__ - long lwpid; - thr_self(&lwpid); - tid = lwpid; + long lwpid; + thr_self(&lwpid); + tid = lwpid; #else - #ifdef __FreeBSD_kernel__ - if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id - #else - tid=syscall(SYS_gettid); - #endif + #ifdef __FreeBSD_kernel__ + if ( (syscall(SYS_thr_self, &tid)) < 0 ) // Thread/Process id + #else + tid=syscall(SYS_gettid); + #endif #endif - return tid; - } + return tid; + } #else - pthread_t pid() { return( pthread_self() ); } + pthread_t pid() { return( pthread_self() ); } #endif - public: - TimerException( const std::string &message ) : Exception( stringtf( "(%d) "+message, (long int)pid() ) ) - { - } - }; - - class TimerThread : public Thread + public: + TimerException( const std::string &message ) : Exception( stringtf( "(%d) "+message, (long int)pid() ) ) { - private: - typedef ThreadData ExpiryFlag; + } + }; - private: - static int mNextTimerId; + class TimerThread : public Thread + { + private: + typedef ThreadData ExpiryFlag; - private: - int mTimerId; - Timer &mTimer; - int mDuration; - int mRepeat; - int mReset; - ExpiryFlag mExpiryFlag; - Mutex mAccessMutex; + private: + static int mNextTimerId; - private: - void quit() - { - cancel(); - } + private: + int mTimerId; + Timer &mTimer; + int mDuration; + int mRepeat; + int mReset; + ExpiryFlag mExpiryFlag; + Mutex mAccessMutex; - public: - TimerThread( Timer &timer, int timeout, bool repeat ); - ~TimerThread(); + private: + void quit() + { + cancel(); + } - void cancel(); - void reset(); - int run(); - }; + public: + TimerThread( Timer &timer, int timeout, bool repeat ); + ~TimerThread(); -protected: - TimerThread mTimerThread; - -protected: - Timer( int timeout, bool repeat=false ); - -public: - virtual ~Timer(); - -protected: - virtual void expire()=0; - -public: void cancel(); void reset(); + int run(); + }; + +protected: + TimerThread mTimerThread; + +protected: + Timer( int timeout, bool repeat=false ); + +public: + virtual ~Timer(); + +protected: + virtual void expire()=0; + +public: + void cancel(); + void reset(); }; #endif // ZM_TIMER_H diff --git a/src/zm_user.cpp b/src/zm_user.cpp index f7822044c..73f5c7932 100644 --- a/src/zm_user.cpp +++ b/src/zm_user.cpp @@ -29,119 +29,119 @@ User::User() { - username[0] = password[0] = 0; - enabled = false; - stream = events = control = monitors = system = PERM_NONE; - monitor_ids = 0; + username[0] = password[0] = 0; + enabled = false; + stream = events = control = monitors = system = PERM_NONE; + monitor_ids = 0; } User::User( MYSQL_ROW &dbrow ) { - int index = 0; - strncpy( username, dbrow[index++], sizeof(username) ); - strncpy( password, dbrow[index++], sizeof(password) ); - enabled = (bool)atoi( dbrow[index++] ); - stream = (Permission)atoi( dbrow[index++] ); - events = (Permission)atoi( dbrow[index++] ); - control = (Permission)atoi( dbrow[index++] ); - monitors = (Permission)atoi( dbrow[index++] ); - system = (Permission)atoi( dbrow[index++] ); - monitor_ids = 0; - char *monitor_ids_str = dbrow[index++]; - if ( monitor_ids_str && *monitor_ids_str ) - { - monitor_ids = new int[strlen(monitor_ids_str)]; - int n_monitor_ids = 0; - const char *ptr = monitor_ids_str; - do - { - int id = 0; - while( isdigit( *ptr ) ) - { - id *= 10; - id += *ptr-'0'; - ptr++; - } - if ( id ) - { - monitor_ids[n_monitor_ids++] = id; - if ( !*ptr ) - break; - } - while ( !isdigit( *ptr ) ) - ptr++; - } while( *ptr ); - monitor_ids[n_monitor_ids] = 0; - } + int index = 0; + strncpy( username, dbrow[index++], sizeof(username) ); + strncpy( password, dbrow[index++], sizeof(password) ); + enabled = (bool)atoi( dbrow[index++] ); + stream = (Permission)atoi( dbrow[index++] ); + events = (Permission)atoi( dbrow[index++] ); + control = (Permission)atoi( dbrow[index++] ); + monitors = (Permission)atoi( dbrow[index++] ); + system = (Permission)atoi( dbrow[index++] ); + monitor_ids = 0; + char *monitor_ids_str = dbrow[index++]; + if ( monitor_ids_str && *monitor_ids_str ) + { + monitor_ids = new int[strlen(monitor_ids_str)]; + int n_monitor_ids = 0; + const char *ptr = monitor_ids_str; + do + { + int id = 0; + while( isdigit( *ptr ) ) + { + id *= 10; + id += *ptr-'0'; + ptr++; + } + if ( id ) + { + monitor_ids[n_monitor_ids++] = id; + if ( !*ptr ) + break; + } + while ( !isdigit( *ptr ) ) + ptr++; + } while( *ptr ); + monitor_ids[n_monitor_ids] = 0; + } } User::~User() { - delete monitor_ids; + delete monitor_ids; } bool User::canAccess( int monitor_id ) { - if ( !monitor_ids ) - { - return( true ); - } - for ( int i = 0; monitor_ids[i]; i++ ) - { - if ( monitor_ids[i] == monitor_id ) - { - return( true ); - } - } - return( false ); + if ( !monitor_ids ) + { + return( true ); + } + for ( int i = 0; monitor_ids[i]; i++ ) + { + if ( monitor_ids[i] == monitor_id ) + { + return( true ); + } + } + return( false ); } // Function to load a user from username and password // Please note that in auth relay mode = none, password is NULL User *zmLoadUser( const char *username, const char *password ) { - char sql[ZM_SQL_SML_BUFSIZ] = ""; - char safer_username[65]; // current db username size is 32 - char safer_password[129]; // current db password size is 64 + char sql[ZM_SQL_SML_BUFSIZ] = ""; + char safer_username[65]; // current db username size is 32 + char safer_password[129]; // current db password size is 64 - // According to docs, size of safer_whatever must be 2*length+1 due to unicode conversions + null terminator. - mysql_real_escape_string(&dbconn, safer_username, username, strlen( username ) ); + // According to docs, size of safer_whatever must be 2*length+1 due to unicode conversions + null terminator. + mysql_real_escape_string(&dbconn, safer_username, username, strlen( username ) ); - if ( password ) { - mysql_real_escape_string(&dbconn, safer_password, password, strlen( password ) ); - snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password ); - } else { - snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username ); - } + if ( password ) { + mysql_real_escape_string(&dbconn, safer_password, password, strlen( password ) ); + snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Password = password('%s') and Enabled = 1", safer_username, safer_password ); + } else { + snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username ); + } - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - MYSQL_RES *result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - int n_users = mysql_num_rows( result ); + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) + { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + int n_users = mysql_num_rows( result ); - if ( n_users != 1 ) - { - Warning( "Unable to authenticate user %s", username ); - return( 0 ); - } + if ( n_users != 1 ) + { + Warning( "Unable to authenticate user %s", username ); + return( 0 ); + } - MYSQL_ROW dbrow = mysql_fetch_row( result ); + MYSQL_ROW dbrow = mysql_fetch_row( result ); - User *user = new User( dbrow ); - Info( "Authenticated user '%s'", user->getUsername() ); + User *user = new User( dbrow ); + Info( "Authenticated user '%s'", user->getUsername() ); - mysql_free_result( result ); + mysql_free_result( result ); - return( user ); + return( user ); } // Function to validate an authentication string @@ -149,102 +149,102 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) { #if HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT #ifdef HAVE_GCRYPT_H - // Special initialisation for libgcrypt - if ( !gcry_check_version( GCRYPT_VERSION ) ) - { - Fatal( "Unable to initialise libgcrypt" ); - } - gcry_control( GCRYCTL_DISABLE_SECMEM, 0 ); - gcry_control( GCRYCTL_INITIALIZATION_FINISHED, 0 ); + // Special initialisation for libgcrypt + if ( !gcry_check_version( GCRYPT_VERSION ) ) + { + Fatal( "Unable to initialise libgcrypt" ); + } + gcry_control( GCRYCTL_DISABLE_SECMEM, 0 ); + gcry_control( GCRYCTL_INITIALIZATION_FINISHED, 0 ); #endif // HAVE_GCRYPT_H - const char *remote_addr = ""; - if ( use_remote_addr ) - { - remote_addr = getenv( "REMOTE_ADDR" ); - if ( !remote_addr ) - { - Warning( "Can't determine remote address, using null" ); - remote_addr = ""; - } - } + const char *remote_addr = ""; + if ( use_remote_addr ) + { + remote_addr = getenv( "REMOTE_ADDR" ); + if ( !remote_addr ) + { + Warning( "Can't determine remote address, using null" ); + remote_addr = ""; + } + } - Debug( 1, "Attempting to authenticate user from auth string '%s'", auth ); - char sql[ZM_SQL_SML_BUFSIZ] = ""; - snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Enabled = 1" ); + Debug( 1, "Attempting to authenticate user from auth string '%s'", auth ); + char sql[ZM_SQL_SML_BUFSIZ] = ""; + snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Enabled = 1" ); - if ( mysql_query( &dbconn, sql ) ) - { - Error( "Can't run query: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } + if ( mysql_query( &dbconn, sql ) ) + { + Error( "Can't run query: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } - MYSQL_RES *result = mysql_store_result( &dbconn ); - if ( !result ) - { - Error( "Can't use query result: %s", mysql_error( &dbconn ) ); - exit( mysql_errno( &dbconn ) ); - } - int n_users = mysql_num_rows( result ); + MYSQL_RES *result = mysql_store_result( &dbconn ); + if ( !result ) + { + Error( "Can't use query result: %s", mysql_error( &dbconn ) ); + exit( mysql_errno( &dbconn ) ); + } + int n_users = mysql_num_rows( result ); - if ( n_users < 1 ) - { - Warning( "Unable to authenticate user" ); - return( 0 ); - } + if ( n_users < 1 ) + { + Warning( "Unable to authenticate user" ); + return( 0 ); + } - while( MYSQL_ROW dbrow = mysql_fetch_row( result ) ) - { - const char *user = dbrow[0]; - const char *pass = dbrow[1]; + while( MYSQL_ROW dbrow = mysql_fetch_row( result ) ) + { + const char *user = dbrow[0]; + const char *pass = dbrow[1]; - char auth_key[512] = ""; - char auth_md5[32+1] = ""; - size_t md5len = 16; - unsigned char md5sum[md5len]; + char auth_key[512] = ""; + char auth_md5[32+1] = ""; + size_t md5len = 16; + unsigned char md5sum[md5len]; - time_t now = time( 0 ); - int max_tries = 2; + time_t now = time( 0 ); + int max_tries = 2; - for ( int i = 0; i < max_tries; i++, now -= (60*60) ) - { - struct tm *now_tm = localtime( &now ); + for ( int i = 0; i < max_tries; i++, now -= (60*60) ) + { + struct tm *now_tm = localtime( &now ); - snprintf( auth_key, sizeof(auth_key), "%s%s%s%s%d%d%d%d", - config.auth_hash_secret, - user, - pass, - remote_addr, - now_tm->tm_hour, - now_tm->tm_mday, - now_tm->tm_mon, - now_tm->tm_year - ); + snprintf( auth_key, sizeof(auth_key), "%s%s%s%s%d%d%d%d", + config.auth_hash_secret, + user, + pass, + remote_addr, + now_tm->tm_hour, + now_tm->tm_mday, + now_tm->tm_mon, + now_tm->tm_year + ); #if HAVE_DECL_MD5 - MD5( (unsigned char *)auth_key, strlen(auth_key), md5sum ); + MD5( (unsigned char *)auth_key, strlen(auth_key), md5sum ); #elif HAVE_DECL_GNUTLS_FINGERPRINT - gnutls_datum_t md5data = { (unsigned char *)auth_key, strlen(auth_key) }; - gnutls_fingerprint( GNUTLS_DIG_MD5, &md5data, md5sum, &md5len ); + gnutls_datum_t md5data = { (unsigned char *)auth_key, strlen(auth_key) }; + gnutls_fingerprint( GNUTLS_DIG_MD5, &md5data, md5sum, &md5len ); #endif - auth_md5[0] = '\0'; - for ( unsigned int j = 0; j < md5len; j++ ) - { - sprintf( &auth_md5[2*j], "%02x", md5sum[j] ); - } - Debug( 1, "Checking auth_key '%s' -> auth_md5 '%s'", auth_key, auth_md5 ); + auth_md5[0] = '\0'; + for ( unsigned int j = 0; j < md5len; j++ ) + { + sprintf( &auth_md5[2*j], "%02x", md5sum[j] ); + } + Debug( 1, "Checking auth_key '%s' -> auth_md5 '%s'", auth_key, auth_md5 ); - if ( !strcmp( auth, auth_md5 ) ) - { - // We have a match - User *user = new User( dbrow ); - Debug(1, "Authenticated user '%s'", user->getUsername() ); - return( user ); - } - } - } + if ( !strcmp( auth, auth_md5 ) ) + { + // We have a match + User *user = new User( dbrow ); + Debug(1, "Authenticated user '%s'", user->getUsername() ); + return( user ); + } + } + } #else // HAVE_DECL_MD5 - Error( "You need to build with gnutls or openssl installed to use hash based authentication" ); + Error( "You need to build with gnutls or openssl installed to use hash based authentication" ); #endif // HAVE_DECL_MD5 - return( 0 ); + return( 0 ); } diff --git a/src/zm_user.h b/src/zm_user.h index 95fb71474..09f5a2f0a 100644 --- a/src/zm_user.h +++ b/src/zm_user.h @@ -39,33 +39,33 @@ class User { public: - typedef enum { PERM_NONE=1, PERM_VIEW, PERM_EDIT } Permission; + typedef enum { PERM_NONE=1, PERM_VIEW, PERM_EDIT } Permission; protected: - char username[32+1]; - char password[64+1]; - bool enabled; - Permission stream; - Permission events; - Permission control; - Permission monitors; - Permission system; - int *monitor_ids; + char username[32+1]; + char password[64+1]; + bool enabled; + Permission stream; + Permission events; + Permission control; + Permission monitors; + Permission system; + int *monitor_ids; public: - User(); - User( MYSQL_ROW &dbrow ); - ~User(); + User(); + User( MYSQL_ROW &dbrow ); + ~User(); - const char *getUsername() const { return( username ); } - const char *getPassword() const { return( password ); } - bool isEnabled() const { return( enabled ); } - Permission getStream() const { return( stream ); } - Permission getEvents() const { return( events ); } - Permission getControl() const { return( control ); } - Permission getMonitors() const { return( monitors ); } - Permission getSystem() const { return( system ); } - bool canAccess( int monitor_id ); + const char *getUsername() const { return( username ); } + const char *getPassword() const { return( password ); } + bool isEnabled() const { return( enabled ); } + Permission getStream() const { return( stream ); } + Permission getEvents() const { return( events ); } + Permission getControl() const { return( control ); } + Permission getMonitors() const { return( monitors ); } + Permission getSystem() const { return( system ); } + bool canAccess( int monitor_id ); }; User *zmLoadUser( const char *username, const char *password=0 ); diff --git a/src/zm_utils.cpp b/src/zm_utils.cpp index e0c65ca61..67af64a66 100644 --- a/src/zm_utils.cpp +++ b/src/zm_utils.cpp @@ -28,256 +28,256 @@ unsigned int sseversion = 0; std::string trimSet(std::string str, std::string trimset) { - // Trim Both leading and trailing sets - size_t startpos = str.find_first_not_of(trimset); // Find the first character position after excluding leading blank spaces - size_t endpos = str.find_last_not_of(trimset); // Find the first character position from reverse af + // Trim Both leading and trailing sets + size_t startpos = str.find_first_not_of(trimset); // Find the first character position after excluding leading blank spaces + size_t endpos = str.find_last_not_of(trimset); // Find the first character position from reverse af - // if all spaces or empty return an empty string - if(( std::string::npos == startpos ) || ( std::string::npos == endpos)) - { - return std::string(""); - } - else - return str.substr( startpos, endpos-startpos+1 ); + // if all spaces or empty return an empty string + if(( std::string::npos == startpos ) || ( std::string::npos == endpos)) + { + return std::string(""); + } + else + return str.substr( startpos, endpos-startpos+1 ); } std::string trimSpaces(std::string str) { - return trimSet(str, " \t"); + return trimSet(str, " \t"); } std::string replaceAll(std::string str, std::string from, std::string to) { - if(from.empty()) - return str; - size_t start_pos = 0; - while((start_pos = str.find(from, start_pos)) != std::string::npos) { - str.replace(start_pos, from.length(), to); - start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' - } + if(from.empty()) return str; + size_t start_pos = 0; + while((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' + } + return str; } const std::string stringtf( const char *format, ... ) { - va_list ap; - char tempBuffer[8192]; - std::string tempString; + va_list ap; + char tempBuffer[8192]; + std::string tempString; - va_start(ap, format ); - vsnprintf( tempBuffer, sizeof(tempBuffer), format , ap ); - va_end(ap); + va_start(ap, format ); + vsnprintf( tempBuffer, sizeof(tempBuffer), format , ap ); + va_end(ap); - tempString = tempBuffer; + tempString = tempBuffer; - return( tempString ); + return( tempString ); } const std::string stringtf( const std::string &format, ... ) { - va_list ap; - char tempBuffer[8192]; - std::string tempString; + va_list ap; + char tempBuffer[8192]; + std::string tempString; - va_start(ap, format ); - vsnprintf( tempBuffer, sizeof(tempBuffer), format.c_str() , ap ); - va_end(ap); + va_start(ap, format ); + vsnprintf( tempBuffer, sizeof(tempBuffer), format.c_str() , ap ); + va_end(ap); - tempString = tempBuffer; + tempString = tempBuffer; - return( tempString ); + return( tempString ); } bool startsWith( const std::string &haystack, const std::string &needle ) { - return( haystack.substr( 0, needle.length() ) == needle ); + return( haystack.substr( 0, needle.length() ) == needle ); } StringVector split( const std::string &string, const std::string chars, int limit ) { - StringVector stringVector; - std::string tempString = string; - std::string::size_type startIndex = 0; - std::string::size_type endIndex = 0; + StringVector stringVector; + std::string tempString = string; + std::string::size_type startIndex = 0; + std::string::size_type endIndex = 0; - //Info( "Looking for '%s' in '%s', limit %d", chars.c_str(), string.c_str(), limit ); - do + //Info( "Looking for '%s' in '%s', limit %d", chars.c_str(), string.c_str(), limit ); + do + { + // Find delimiters + endIndex = string.find_first_of( chars, startIndex ); + //Info( "Got endIndex at %d", endIndex ); + if ( endIndex > 0 ) { - // Find delimiters - endIndex = string.find_first_of( chars, startIndex ); - //Info( "Got endIndex at %d", endIndex ); - if ( endIndex > 0 ) - { - //Info( "Adding '%s'", string.substr( startIndex, endIndex-startIndex ).c_str() ); - stringVector.push_back( string.substr( startIndex, endIndex-startIndex ) ); - } - if ( endIndex == std::string::npos ) - break; - // Find non-delimiters - startIndex = tempString.find_first_not_of( chars, endIndex ); - if ( limit && (stringVector.size() == (unsigned int)(limit-1)) ) - { - stringVector.push_back( string.substr( startIndex ) ); - break; - } - //Info( "Got new startIndex at %d", startIndex ); - } while ( startIndex != std::string::npos ); - //Info( "Finished with %d strings", stringVector.size() ); + //Info( "Adding '%s'", string.substr( startIndex, endIndex-startIndex ).c_str() ); + stringVector.push_back( string.substr( startIndex, endIndex-startIndex ) ); + } + if ( endIndex == std::string::npos ) + break; + // Find non-delimiters + startIndex = tempString.find_first_not_of( chars, endIndex ); + if ( limit && (stringVector.size() == (unsigned int)(limit-1)) ) + { + stringVector.push_back( string.substr( startIndex ) ); + break; + } + //Info( "Got new startIndex at %d", startIndex ); + } while ( startIndex != std::string::npos ); + //Info( "Finished with %d strings", stringVector.size() ); - return( stringVector ); + return( stringVector ); } const std::string join(const StringVector v, const char * delim ) { - std::stringstream ss; + std::stringstream ss; - for(size_t i = 0; i < v.size(); ++i) { - if(i != 0) - ss << ","; - ss << v[i]; - } - return ss.str(); + for(size_t i = 0; i < v.size(); ++i) { + if(i != 0) + ss << ","; + ss << v[i]; + } + return ss.str(); } const std::string base64Encode( const std::string &inString ) { - static char base64_table[64] = { '\0' }; + static char base64_table[64] = { '\0' }; - if ( !base64_table[0] ) - { - int i = 0; - for ( char c = 'A'; c <= 'Z'; c++ ) - base64_table[i++] = c; - for ( char c = 'a'; c <= 'z'; c++ ) - base64_table[i++] = c; - for ( char c = '0'; c <= '9'; c++ ) - base64_table[i++] = c; - base64_table[i++] = '+'; - base64_table[i++] = '/'; - } + if ( !base64_table[0] ) + { + int i = 0; + for ( char c = 'A'; c <= 'Z'; c++ ) + base64_table[i++] = c; + for ( char c = 'a'; c <= 'z'; c++ ) + base64_table[i++] = c; + for ( char c = '0'; c <= '9'; c++ ) + base64_table[i++] = c; + base64_table[i++] = '+'; + base64_table[i++] = '/'; + } - std::string outString; - outString.reserve( 2 * inString.size() ); + std::string outString; + outString.reserve( 2 * inString.size() ); - const char *inPtr = inString.c_str(); - while( *inPtr ) - { - unsigned char selection = *inPtr >> 2; - unsigned char remainder = (*inPtr++ & 0x03) << 4; - outString += base64_table[selection]; + const char *inPtr = inString.c_str(); + while( *inPtr ) + { + unsigned char selection = *inPtr >> 2; + unsigned char remainder = (*inPtr++ & 0x03) << 4; + outString += base64_table[selection]; - if ( *inPtr ) - { - selection = remainder | (*inPtr >> 4); - remainder = (*inPtr++ & 0x0f) << 2; - outString += base64_table[selection]; - - if ( *inPtr ) - { - selection = remainder | (*inPtr >> 6); - outString += base64_table[selection]; - selection = (*inPtr++ & 0x3f); - outString += base64_table[selection]; - } - else - { - outString += base64_table[remainder]; - outString += '='; - } - } - else - { - outString += base64_table[remainder]; - outString += '='; - outString += '='; - } - } - return( outString ); + if ( *inPtr ) + { + selection = remainder | (*inPtr >> 4); + remainder = (*inPtr++ & 0x0f) << 2; + outString += base64_table[selection]; + + if ( *inPtr ) + { + selection = remainder | (*inPtr >> 6); + outString += base64_table[selection]; + selection = (*inPtr++ & 0x3f); + outString += base64_table[selection]; + } + else + { + outString += base64_table[remainder]; + outString += '='; + } + } + else + { + outString += base64_table[remainder]; + outString += '='; + outString += '='; + } + } + return( outString ); } int split(const char* string, const char delim, std::vector& items) { - if(string == NULL) - return -1; + if(string == NULL) + return -1; - if(string[0] == 0) - return -2; + if(string[0] == 0) + return -2; - std::string str(string); - size_t pos; - - while(true) { - pos = str.find(delim); - items.push_back(str.substr(0, pos)); - str.erase(0, pos+1); + std::string str(string); + size_t pos; + + while(true) { + pos = str.find(delim); + items.push_back(str.substr(0, pos)); + str.erase(0, pos+1); - if(pos == std::string::npos) - break; - } + if(pos == std::string::npos) + break; + } - return items.size(); + return items.size(); } int pairsplit(const char* string, const char delim, std::string& name, std::string& value) { - if(string == NULL) - return -1; + if(string == NULL) + return -1; - if(string[0] == 0) - return -2; + if(string[0] == 0) + return -2; - std::string str(string); - size_t pos = str.find(delim); + std::string str(string); + size_t pos = str.find(delim); - if(pos == std::string::npos || pos == 0 || pos >= str.length()) - return -3; + if(pos == std::string::npos || pos == 0 || pos >= str.length()) + return -3; - name = str.substr(0, pos); - value = str.substr(pos+1, std::string::npos); + name = str.substr(0, pos); + value = str.substr(pos+1, std::string::npos); - return 0; + return 0; } /* Sets sse_version */ void ssedetect() { #if (defined(__i386__) || defined(__x86_64__)) - /* x86 or x86-64 processor */ - uint32_t r_edx, r_ecx; - - __asm__ __volatile__( + /* x86 or x86-64 processor */ + uint32_t r_edx, r_ecx; + + __asm__ __volatile__( #if defined(__i386__) - "pushl %%ebx;\n\t" + "pushl %%ebx;\n\t" #endif - "mov $0x1,%%eax\n\t" - "cpuid\n\t" + "mov $0x1,%%eax\n\t" + "cpuid\n\t" #if defined(__i386__) - "popl %%ebx;\n\t" + "popl %%ebx;\n\t" #endif - : "=d" (r_edx), "=c" (r_ecx) - : - : "%eax" + : "=d" (r_edx), "=c" (r_ecx) + : + : "%eax" #if !defined(__i386__) - , "%ebx" + , "%ebx" #endif - ); - - if (r_ecx & 0x00000200) { - sseversion = 35; /* SSSE3 */ - Debug(1,"Detected a x86\\x86-64 processor with SSSE3"); - } else if (r_ecx & 0x00000001) { - sseversion = 30; /* SSE3 */ - Debug(1,"Detected a x86\\x86-64 processor with SSE3"); - } else if (r_edx & 0x04000000) { - sseversion = 20; /* SSE2 */ - Debug(1,"Detected a x86\\x86-64 processor with SSE2"); - } else if (r_edx & 0x02000000) { - sseversion = 10; /* SSE */ - Debug(1,"Detected a x86\\x86-64 processor with SSE"); - } else { - sseversion = 0; - Debug(1,"Detected a x86\\x86-64 processor"); - } - + ); + + if (r_ecx & 0x00000200) { + sseversion = 35; /* SSSE3 */ + Debug(1,"Detected a x86\\x86-64 processor with SSSE3"); + } else if (r_ecx & 0x00000001) { + sseversion = 30; /* SSE3 */ + Debug(1,"Detected a x86\\x86-64 processor with SSE3"); + } else if (r_edx & 0x04000000) { + sseversion = 20; /* SSE2 */ + Debug(1,"Detected a x86\\x86-64 processor with SSE2"); + } else if (r_edx & 0x02000000) { + sseversion = 10; /* SSE */ + Debug(1,"Detected a x86\\x86-64 processor with SSE"); + } else { + sseversion = 0; + Debug(1,"Detected a x86\\x86-64 processor"); + } + #else - /* Non x86 or x86-64 processor, SSE2 is not available */ - Debug(1,"Detected a non x86\\x86-64 processor"); - sseversion = 0; + /* Non x86 or x86-64 processor, SSE2 is not available */ + Debug(1,"Detected a non x86\\x86-64 processor"); + sseversion = 0; #endif } @@ -288,60 +288,60 @@ __attribute__((noinline,__target__("sse2"))) #endif void* sse2_aligned_memcpy(void* dest, const void* src, size_t bytes) { #if ((defined(__i386__) || defined(__x86_64__) || defined(ZM_KEEP_SSE)) && !defined(ZM_STRIP_SSE)) - if(bytes > 128) { - unsigned int remainder = bytes % 128; - const uint8_t* lastsrc = (uint8_t*)src + (bytes - remainder); + if(bytes > 128) { + unsigned int remainder = bytes % 128; + const uint8_t* lastsrc = (uint8_t*)src + (bytes - remainder); - __asm__ __volatile__( - "sse2_copy_iter:\n\t" - "movdqa (%0),%%xmm0\n\t" - "movdqa 0x10(%0),%%xmm1\n\t" - "movdqa 0x20(%0),%%xmm2\n\t" - "movdqa 0x30(%0),%%xmm3\n\t" - "movdqa 0x40(%0),%%xmm4\n\t" - "movdqa 0x50(%0),%%xmm5\n\t" - "movdqa 0x60(%0),%%xmm6\n\t" - "movdqa 0x70(%0),%%xmm7\n\t" - "movntdq %%xmm0,(%1)\n\t" - "movntdq %%xmm1,0x10(%1)\n\t" - "movntdq %%xmm2,0x20(%1)\n\t" - "movntdq %%xmm3,0x30(%1)\n\t" - "movntdq %%xmm4,0x40(%1)\n\t" - "movntdq %%xmm5,0x50(%1)\n\t" - "movntdq %%xmm6,0x60(%1)\n\t" - "movntdq %%xmm7,0x70(%1)\n\t" - "add $0x80, %0\n\t" - "add $0x80, %1\n\t" - "cmp %2, %0\n\t" - "jb sse2_copy_iter\n\t" - "test %3, %3\n\t" - "jz sse2_copy_finish\n\t" - "cld\n\t" - "rep movsb\n\t" - "sse2_copy_finish:\n\t" - : - : "S" (src), "D" (dest), "r" (lastsrc), "c" (remainder) - : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" - ); + __asm__ __volatile__( + "sse2_copy_iter:\n\t" + "movdqa (%0),%%xmm0\n\t" + "movdqa 0x10(%0),%%xmm1\n\t" + "movdqa 0x20(%0),%%xmm2\n\t" + "movdqa 0x30(%0),%%xmm3\n\t" + "movdqa 0x40(%0),%%xmm4\n\t" + "movdqa 0x50(%0),%%xmm5\n\t" + "movdqa 0x60(%0),%%xmm6\n\t" + "movdqa 0x70(%0),%%xmm7\n\t" + "movntdq %%xmm0,(%1)\n\t" + "movntdq %%xmm1,0x10(%1)\n\t" + "movntdq %%xmm2,0x20(%1)\n\t" + "movntdq %%xmm3,0x30(%1)\n\t" + "movntdq %%xmm4,0x40(%1)\n\t" + "movntdq %%xmm5,0x50(%1)\n\t" + "movntdq %%xmm6,0x60(%1)\n\t" + "movntdq %%xmm7,0x70(%1)\n\t" + "add $0x80, %0\n\t" + "add $0x80, %1\n\t" + "cmp %2, %0\n\t" + "jb sse2_copy_iter\n\t" + "test %3, %3\n\t" + "jz sse2_copy_finish\n\t" + "cld\n\t" + "rep movsb\n\t" + "sse2_copy_finish:\n\t" + : + : "S" (src), "D" (dest), "r" (lastsrc), "c" (remainder) + : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" + ); - } else { - /* Standard memcpy */ - __asm__ __volatile__("cld; rep movsb" :: "S"(src), "D"(dest), "c"(bytes) : "cc", "memory"); - } + } else { + /* Standard memcpy */ + __asm__ __volatile__("cld; rep movsb" :: "S"(src), "D"(dest), "c"(bytes) : "cc", "memory"); + } #else - /* Non x86\x86-64 platform, use memcpy */ - memcpy(dest,src,bytes); + /* Non x86\x86-64 platform, use memcpy */ + memcpy(dest,src,bytes); #endif - return dest; + return dest; } void timespec_diff(struct timespec *start, struct timespec *end, struct timespec *diff) { - if (((end->tv_nsec)-(start->tv_nsec))<0) { - diff->tv_sec = end->tv_sec-start->tv_sec-1; - diff->tv_nsec = 1000000000+end->tv_nsec-start->tv_nsec; - } else { - diff->tv_sec = end->tv_sec-start->tv_sec; - diff->tv_nsec = end->tv_nsec-start->tv_nsec; - } + if (((end->tv_nsec)-(start->tv_nsec))<0) { + diff->tv_sec = end->tv_sec-start->tv_sec-1; + diff->tv_nsec = 1000000000+end->tv_nsec-start->tv_nsec; + } else { + diff->tv_sec = end->tv_sec-start->tv_sec; + diff->tv_nsec = end->tv_nsec-start->tv_nsec; + } } diff --git a/src/zm_utils.h b/src/zm_utils.h index 063c74b7d..a6cb2e150 100644 --- a/src/zm_utils.h +++ b/src/zm_utils.h @@ -46,12 +46,12 @@ int pairsplit(const char* string, const char delim, std::string& name, std::stri inline int max( int a, int b ) { - return( a>=b?a:b ); + return( a>=b?a:b ); } inline int min( int a, int b ) { - return( a<=b?a:b ); + return( a<=b?a:b ); } void ssedetect(); diff --git a/src/zm_videostore.cpp b/src/zm_videostore.cpp index 575070acc..f55dcaabd 100644 --- a/src/zm_videostore.cpp +++ b/src/zm_videostore.cpp @@ -29,277 +29,321 @@ #include "zm_videostore.h" extern "C"{ -#include "libavutil/time.h" + #include "libavutil/time.h" } VideoStore::VideoStore(const char *filename_in, const char *format_in, - AVStream *input_st, AVStream *inpaud_st, + AVStream *input_st, + AVStream *inpaud_st, int64_t nStartTime) { - AVDictionary *pmetadata = NULL; - int dsr; + AVDictionary *pmetadata = NULL; + int dsr; - //store inputs in variables local to class - filename = filename_in; - format = format_in; - - keyframeMessage = false; - keyframeSkipNumber = 0; + //store inputs in variables local to class + filename = filename_in; + format = format_in; + keyframeMessage = false; + keyframeSkipNumber = 0; - Info("Opening video storage stream %s\n", filename); + Info("Opening video storage stream %s format: %d\n", filename, format); - //Init everything we need - int ret; - av_register_all(); + //Init everything we need + int ret; + av_register_all(); - avformat_alloc_output_context2(&oc, NULL, NULL, filename); - - //Couldn't deduce format from filename, trying from format name + ret = avformat_alloc_output_context2(&oc, NULL, NULL, filename); + if ( ret < 0 ) { + Warning("Could not create video storage stream %s as no output context" + " could be assigned based on filename: %s", + filename, + av_make_error_string(ret).c_str() + ); + } + + //Couldn't deduce format from filename, trying from format name + if (!oc) { + avformat_alloc_output_context2(&oc, NULL, format, filename); if (!oc) { - avformat_alloc_output_context2(&oc, NULL, format, filename); - if (!oc) { - Fatal("Could not create video storage stream %s as no output context" - " could not be assigned based on filename or format %s", - filename, format); - } + Fatal("Could not create video storage stream %s as no output context" + " could not be assigned based on filename or format %s", + filename, format); } + } - dsr = av_dict_set(&pmetadata, "title", "Zoneminder Security Recording", 0); - if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__ ); + dsr = av_dict_set(&pmetadata, "title", "Zoneminder Security Recording", 0); + if (dsr < 0) Warning("%s:%d: title set failed", __FILE__, __LINE__ ); - oc->metadata = pmetadata; - - fmt = oc->oformat; - - video_st = avformat_new_stream(oc, input_st->codec->codec); - if (!video_st) { - Fatal("Unable to create video out stream\n"); - } - - ret = avcodec_copy_context(video_st->codec, input_st->codec); - if (ret < 0) { - Fatal("Unable to copy input video context to output video context " - "%s\n", av_make_error_string(ret).c_str()); - } + oc->metadata = pmetadata; - video_st->codec->codec_tag = 0; - if (oc->oformat->flags & AVFMT_GLOBALHEADER) { - video_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; - } - - if (inpaud_st) { - audio_st = avformat_new_stream(oc, inpaud_st->codec->codec); - if (!audio_st) { - Fatal("Unable to create audio out stream\n"); - } - ret=avcodec_copy_context(audio_st->codec, inpaud_st->codec); - if (ret < 0) { - Fatal("Unable to copy audio context %s\n", av_make_error_string(ret).c_str()); - } - audio_st->codec->codec_tag = 0; - if (oc->oformat->flags & AVFMT_GLOBALHEADER) { - audio_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; - } + fmt = oc->oformat; + + video_st = avformat_new_stream(oc, (AVCodec *)input_st->codec->codec); + if (!video_st) { + Fatal("Unable to create video out stream\n"); + } + + ret = avcodec_copy_context(video_st->codec, input_st->codec); + if (ret < 0) { + Fatal("Unable to copy input video context to output video context %s\n", + av_make_error_string(ret).c_str()); + } + + video_st->codec->codec_tag = 0; + if (oc->oformat->flags & AVFMT_GLOBALHEADER) { + video_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; + } + + if (inpaud_st) { + + audio_st = avformat_new_stream(oc, (AVCodec *)inpaud_st->codec->codec); + if (!audio_st) { + Error("Unable to create audio out stream\n"); + audio_st = NULL; } else { - audio_st = NULL; - } - - /* open the output file, if needed */ - if (!(fmt->flags & AVFMT_NOFILE)) { - ret = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,NULL,NULL); - if (ret < 0) { - Fatal("Could not open output file '%s': %s\n", filename, - av_make_error_string(ret).c_str()); - } + ret = avcodec_copy_context(audio_st->codec, inpaud_st->codec); + if (ret < 0) { + Fatal("Unable to copy audio context %s\n", av_make_error_string(ret).c_str()); + } + audio_st->codec->codec_tag = 0; + if ( audio_st->codec->channels > 1 ) { + Warning("Audio isn't mono, changing it."); + audio_st->codec->channels = 1; + } + if (oc->oformat->flags & AVFMT_GLOBALHEADER) { + audio_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER; + } } + } else { + Debug(3, "No Audio output stream"); + audio_st = NULL; + } - - /* Write the stream header, if any. */ - ret = avformat_write_header(oc, NULL); + /* open the output file, if needed */ + if (!(fmt->flags & AVFMT_NOFILE)) { + ret = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE,NULL,NULL); if (ret < 0) { - Fatal("Error occurred when writing output file header: %s\n", - av_make_error_string(ret).c_str()); + Fatal("Could not open output file '%s': %s\n", filename, + av_make_error_string(ret).c_str()); } - - prevDts = 0; - startPts = 0; - startDts = 0; - filter_in_rescale_delta_last = AV_NOPTS_VALUE; + } - startTime=av_gettime()-nStartTime;//oc->start_time; - Info("VideoStore startTime=%d\n",startTime); -} + //av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0); + //if ((ret = avformat_write_header(ctx, &opts)) < 0) { + //} + //os->ctx_inited = 1; + //avio_flush(ctx->pb); + //av_dict_free(&opts); + + /* Write the stream header, if any. */ + ret = avformat_write_header(oc, NULL); + if (ret < 0) { + zm_dump_stream_format( oc, 0, 0, 1 ); + Fatal("Error occurred when writing output file header to %s: %s\n", + filename, + av_make_error_string(ret).c_str()); + } + + prevDts = 0; + startPts = 0; + startDts = 0; + filter_in_rescale_delta_last = AV_NOPTS_VALUE; + + startTime=av_gettime()-nStartTime;//oc->start_time; + Info("VideoStore startTime=%d\n",startTime); +} // VideoStore::VideoStore VideoStore::~VideoStore(){ - /* Write the trailer before close */ - if ( int rc = av_write_trailer(oc) ) { - Error("Error writing trailer %s", av_err2str( rc ) ); - } else { - Debug(3, "Sucess Writing trailer"); - } - + /* Write the trailer before close */ + if ( int rc = av_write_trailer(oc) ) { + Error("Error writing trailer %s", av_err2str( rc ) ); + } else { + Debug(3, "Sucess Writing trailer"); + } + + // I wonder if we should be closing the file first. + // I also wonder if we really need to be doing all the context allocation/de-allocation constantly, or whether we can just re-use it. Just do a file open/close/writeheader/etc. + // What if we were only doing audio recording? + if ( video_st ) { avcodec_close(video_st->codec); - if (audio_st) { - avcodec_close(audio_st->codec); - } - - if (!(fmt->flags & AVFMT_NOFILE)) { + } + if (audio_st) { + avcodec_close(audio_st->codec); + } + + // WHen will be not using a file ? + if (!(fmt->flags & AVFMT_NOFILE)) { /* Close the output file. */ - if ( int rc= avio_close(oc->pb) ) { - Error("Error closing avio %s", av_err2str( rc ) ); - } + if ( int rc = avio_close(oc->pb) ) { + Error("Error closing avio %s", av_err2str( rc ) ); } - - /* free the stream */ - avformat_free_context(oc); + } else { + Debug(3, "Not closing avio because we are not writing to a file."); + } + + /* free the stream */ + avformat_free_context(oc); } void VideoStore::dumpPacket( AVPacket *pkt ){ - char b[10240]; + char b[10240]; - snprintf(b, sizeof(b), " pts: %" PRId64 ", dts: %" PRId64 ", data: %p, size: %d, sindex: %d, dflags: %04x, s-pos: %" PRId64 ", c-duration: %" PRId64 "\n" - , pkt->pts - , pkt->dts - , pkt->data - , pkt->size - , pkt->stream_index - , pkt->flags - , pkt->pos - , pkt->convergence_duration - ); - Info("%s:%d:DEBUG: %s", __FILE__, __LINE__, b); + snprintf(b, sizeof(b), " pts: %" PRId64 ", dts: %" PRId64 ", data: %p, size: %d, sindex: %d, dflags: %04x, s-pos: %" PRId64 ", c-duration: %" PRId64 "\n" + , pkt->pts + , pkt->dts + , pkt->data + , pkt->size + , pkt->stream_index + , pkt->flags + , pkt->pos + , pkt->convergence_duration + ); + Info("%s:%d:DEBUG: %s", __FILE__, __LINE__, b); } int VideoStore::writeVideoFramePacket(AVPacket *ipkt, AVStream *input_st){//, AVPacket *lastKeyframePkt){ - int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, video_st->time_base); - - AVPacket opkt, safepkt; - AVPicture pict; - - av_init_packet(&opkt); + int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, video_st->time_base); - //Scale the PTS of the outgoing packet to be the correct time base - if (ipkt->pts != AV_NOPTS_VALUE) { - opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, video_st->time_base) - ost_tb_start_time; - } else { - opkt.pts = AV_NOPTS_VALUE; - } - - //Scale the DTS of the outgoing packet to be the correct time base - if(ipkt->dts == AV_NOPTS_VALUE) { - opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, video_st->time_base); - } else { - opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, video_st->time_base); - } + AVPacket opkt, safepkt; + AVPicture pict; - opkt.dts -= ost_tb_start_time; + av_init_packet(&opkt); - opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, video_st->time_base); - opkt.flags = ipkt->flags; - opkt.pos=-1; + //Scale the PTS of the outgoing packet to be the correct time base + if (ipkt->pts != AV_NOPTS_VALUE) { + opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, video_st->time_base) - ost_tb_start_time; + } else { + opkt.pts = AV_NOPTS_VALUE; + } - opkt.data = ipkt->data; - opkt.size = ipkt->size; - opkt.stream_index = ipkt->stream_index; - /*opkt.flags |= AV_PKT_FLAG_KEY;*/ - - if (video_st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (fmt->flags & AVFMT_RAWPICTURE)) { - /* store AVPicture in AVPacket, as expected by the output format */ - avpicture_fill(&pict, opkt.data, video_st->codec->pix_fmt, video_st->codec->width, video_st->codec->height); - opkt.data = (uint8_t *)&pict; - opkt.size = sizeof(AVPicture); - opkt.flags |= AV_PKT_FLAG_KEY; + //Scale the DTS of the outgoing packet to be the correct time base + if(ipkt->dts == AV_NOPTS_VALUE) { + opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, video_st->time_base); + } else { + opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, video_st->time_base); + } + + opkt.dts -= ost_tb_start_time; + + opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, video_st->time_base); + opkt.flags = ipkt->flags; + opkt.pos=-1; + + opkt.data = ipkt->data; + opkt.size = ipkt->size; + opkt.stream_index = ipkt->stream_index; + /*opkt.flags |= AV_PKT_FLAG_KEY;*/ + + if (video_st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (fmt->flags & AVFMT_RAWPICTURE)) { + /* store AVPicture in AVPacket, as expected by the output format */ + avpicture_fill(&pict, opkt.data, video_st->codec->pix_fmt, video_st->codec->width, video_st->codec->height); + opkt.data = (uint8_t *)&pict; + opkt.size = sizeof(AVPicture); + opkt.flags |= AV_PKT_FLAG_KEY; + } + + memcpy(&safepkt, &opkt, sizeof(AVPacket)); + + if ((opkt.data == NULL)||(opkt.size < 1)) { + Warning("%s:%d: Mangled AVPacket: discarding frame", __FILE__, __LINE__ ); + dumpPacket(&opkt); + + } else if ((prevDts > 0) && (prevDts >= opkt.dts)) { + Warning("%s:%d: DTS out of order: %lld \u226E %lld; discarding frame", __FILE__, __LINE__, prevDts, opkt.dts); + prevDts = opkt.dts; + dumpPacket(&opkt); + + } else { + int ret; + + prevDts = opkt.dts; // Unsure if av_interleaved_write_frame() clobbers opkt.dts when out of order, so storing in advance + ret = av_interleaved_write_frame(oc, &opkt); + if(ret<0){ + // There's nothing we can really do if the frame is rejected, just drop it and get on with the next + Warning("%s:%d: Writing frame [av_interleaved_write_frame()] failed: %s(%d) ", __FILE__, __LINE__, av_make_error_string(ret).c_str(), (ret)); + dumpPacket(&safepkt); } - - memcpy(&safepkt, &opkt, sizeof(AVPacket)); - - if ((opkt.data == NULL)||(opkt.size < 1)) { - Warning("%s:%d: Mangled AVPacket: discarding frame", __FILE__, __LINE__ ); - dumpPacket(&opkt); - - } else if ((prevDts > 0) && (prevDts >= opkt.dts)) { - Warning("%s:%d: DTS out of order: %lld \u226E %lld; discarding frame", __FILE__, __LINE__, prevDts, opkt.dts); - prevDts = opkt.dts; - dumpPacket(&opkt); - - } else { - int ret; - - prevDts = opkt.dts; // Unsure if av_interleaved_write_frame() clobbers opkt.dts when out of order, so storing in advance - ret = av_interleaved_write_frame(oc, &opkt); - if(ret<0){ - // There's nothing we can really do if the frame is rejected, just drop it and get on with the next - Warning("%s:%d: Writing frame [av_interleaved_write_frame()] failed: %s(%d) ", __FILE__, __LINE__, av_make_error_string(ret).c_str(), (ret)); - dumpPacket(&safepkt); - } - } + } - av_free_packet(&opkt); + av_free_packet(&opkt); + + return 0; - return 0; - } int VideoStore::writeAudioFramePacket(AVPacket *ipkt, AVStream *input_st){ - if(!audio_st) - return -1;//FIXME -ve return codes do not free packet in ffmpeg_camera at the moment - /*if(!keyframeMessage) - return -1;*/ - - int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, video_st->time_base); - - AVPacket opkt; - - av_init_packet(&opkt); + if(!audio_st) { + Error("Called writeAudioFramePacket when no audio_st"); + return -1;//FIXME -ve return codes do not free packet in ffmpeg_camera at the moment + } + /*if(!keyframeMessage) + return -1;*/ + //zm_dump_stream_format( oc, ipkt->stream_index, 0, 1 ); - - //Scale the PTS of the outgoing packet to be the correct time base - if (ipkt->pts != AV_NOPTS_VALUE) - opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, audio_st->time_base) - ost_tb_start_time; - else - opkt.pts = AV_NOPTS_VALUE; - - //Scale the DTS of the outgoing packet to be the correct time base - if(ipkt->dts == AV_NOPTS_VALUE) { - opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, audio_st->time_base); -Debug(3, "ipkt->dts == AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts ); - } else - opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, audio_st->time_base); - opkt.dts -= ost_tb_start_time; - - if (audio_st->codec->codec_type == AVMEDIA_TYPE_AUDIO && ipkt->dts != AV_NOPTS_VALUE) { - Debug( 3, "code is audio, dts != AV_NOPTS_VALUE " ); - int duration = av_get_audio_frame_duration(input_st->codec, ipkt->size); - if(!duration) - duration = input_st->codec->frame_size; - - //FIXME where to get filter_in_rescale_delta_last - //FIXME av_rescale_delta doesn't exist in ubuntu vivid libavtools - opkt.dts = opkt.pts = av_rescale_delta(input_st->time_base, ipkt->dts, - (AVRational){1, input_st->codec->sample_rate}, duration, &filter_in_rescale_delta_last, - audio_st->time_base) - ost_tb_start_time; - } - - opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, audio_st->time_base); - opkt.pos=-1; - opkt.flags = ipkt->flags; - - opkt.data = ipkt->data; - opkt.size = ipkt->size; - opkt.stream_index = ipkt->stream_index; - - int ret; - ret = av_interleaved_write_frame(oc, &opkt); - if(ret!=0){ - Fatal("Error encoding audio frame packet: %s\n", av_make_error_string(ret).c_str()); - } - - av_free_packet(&opkt); - return 0; + // What is this doing? Getting the time of the start of this video chunk? Does that actually make sense? + int64_t ost_tb_start_time = av_rescale_q(startTime, AV_TIME_BASE_Q, audio_st->time_base); + + AVPacket opkt; + + av_init_packet(&opkt); + Debug(3, "after init packet" ); + + + //Scale the PTS of the outgoing packet to be the correct time base + if (ipkt->pts != AV_NOPTS_VALUE) { + Debug(3, "Rescaling output pts"); + opkt.pts = av_rescale_q(ipkt->pts-startPts, input_st->time_base, audio_st->time_base) - ost_tb_start_time; + } else { + Debug(3, "Setting output pts to AV_NOPTS_VALUE"); + opkt.pts = AV_NOPTS_VALUE; + } + + //Scale the DTS of the outgoing packet to be the correct time base + if(ipkt->dts == AV_NOPTS_VALUE) { + Debug(4, "ipkt->dts == AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts ); + opkt.dts = av_rescale_q(input_st->cur_dts-startDts, AV_TIME_BASE_Q, audio_st->time_base); + Debug(4, "ipkt->dts == AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts ); + } else { + Debug(4, "ipkt->dts != AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts ); + opkt.dts = av_rescale_q(ipkt->dts-startDts, input_st->time_base, audio_st->time_base); + Debug(4, "ipkt->dts != AV_NOPTS_VALUE %d to %d", AV_NOPTS_VALUE, opkt.dts ); + } + opkt.dts -= ost_tb_start_time; + + // Seems like it would be really weird for the codec type to NOT be audiu + if (audio_st->codec->codec_type == AVMEDIA_TYPE_AUDIO && ipkt->dts != AV_NOPTS_VALUE) { + Debug( 4, "code is audio, dts != AV_NOPTS_VALUE " ); + int duration = av_get_audio_frame_duration(input_st->codec, ipkt->size); + if(!duration) + duration = input_st->codec->frame_size; + + //FIXME where to get filter_in_rescale_delta_last + //FIXME av_rescale_delta doesn't exist in ubuntu vivid libavtools + opkt.dts = opkt.pts = av_rescale_delta(input_st->time_base, ipkt->dts, + (AVRational){1, input_st->codec->sample_rate}, duration, &filter_in_rescale_delta_last, + audio_st->time_base) - ost_tb_start_time; + } + + opkt.duration = av_rescale_q(ipkt->duration, input_st->time_base, audio_st->time_base); + opkt.pos=-1; + opkt.flags = ipkt->flags; + + opkt.data = ipkt->data; + opkt.size = ipkt->size; + opkt.stream_index = ipkt->stream_index; + + int ret; + ret = av_interleaved_write_frame(oc, &opkt); + if(ret!=0){ + Fatal("Error encoding audio frame packet: %s\n", av_make_error_string(ret).c_str()); + } + Debug(4,"Success writing audio frame" ); + av_free_packet(&opkt); + return 0; } diff --git a/src/zm_zone.h b/src/zm_zone.h index d40b52b75..9b8a63747 100644 --- a/src/zm_zone.h +++ b/src/zm_zone.h @@ -35,141 +35,141 @@ class Monitor; class Zone { protected: - struct Range - { - int lo_x; - int hi_x; - int off_x; - }; + struct Range + { + int lo_x; + int hi_x; + int off_x; + }; public: - typedef enum { ACTIVE=1, INCLUSIVE, EXCLUSIVE, PRECLUSIVE, INACTIVE, PRIVACY } ZoneType; - typedef enum { ALARMED_PIXELS=1, FILTERED_PIXELS, BLOBS } CheckMethod; + typedef enum { ACTIVE=1, INCLUSIVE, EXCLUSIVE, PRECLUSIVE, INACTIVE, PRIVACY } ZoneType; + typedef enum { ALARMED_PIXELS=1, FILTERED_PIXELS, BLOBS } CheckMethod; protected: - // Inputs - Monitor *monitor; + // Inputs + Monitor *monitor; - int id; - char *label; - ZoneType type; - Polygon polygon; - Rgb alarm_rgb; - CheckMethod check_method; + int id; + char *label; + ZoneType type; + Polygon polygon; + Rgb alarm_rgb; + CheckMethod check_method; - int min_pixel_threshold; - int max_pixel_threshold; + int min_pixel_threshold; + int max_pixel_threshold; - int min_alarm_pixels; - int max_alarm_pixels; + int min_alarm_pixels; + int max_alarm_pixels; - Coord filter_box; - int min_filter_pixels; - int max_filter_pixels; + Coord filter_box; + int min_filter_pixels; + int max_filter_pixels; - int min_blob_pixels; - int max_blob_pixels; - int min_blobs; - int max_blobs; + int min_blob_pixels; + int max_blob_pixels; + int min_blobs; + int max_blobs; - int overload_frames; - int extend_alarm_frames; + int overload_frames; + int extend_alarm_frames; - // Outputs/Statistics - bool alarmed; - int pixel_diff; - unsigned int alarm_pixels; - int alarm_filter_pixels; - int alarm_blob_pixels; - int alarm_blobs; - int min_blob_size; - int max_blob_size; - Box alarm_box; - Coord alarm_centre; - unsigned int score; - Image *pg_image; - Range *ranges; - Image *image; + // Outputs/Statistics + bool alarmed; + int pixel_diff; + unsigned int alarm_pixels; + int alarm_filter_pixels; + int alarm_blob_pixels; + int alarm_blobs; + int min_blob_size; + int max_blob_size; + Box alarm_box; + Coord alarm_centre; + unsigned int score; + Image *pg_image; + Range *ranges; + Image *image; - int overload_count; - int extend_alarm_count; + int overload_count; + int extend_alarm_count; protected: - void Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_type, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold, int p_max_pixel_threshold, int p_min_alarm_pixels, int p_max_alarm_pixels, const Coord &p_filter_box, int p_min_filter_pixels, int p_max_filter_pixels, int p_min_blob_pixels, int p_max_blob_pixels, int p_min_blobs, int p_max_blobs, int p_overload_frames, int p_extend_alarm_frames ); - void std_alarmedpixels(Image* pdiff_image, const Image* ppoly_image, unsigned int* pixel_count, unsigned int* pixel_sum); - + void Setup( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_type, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold, int p_max_pixel_threshold, int p_min_alarm_pixels, int p_max_alarm_pixels, const Coord &p_filter_box, int p_min_filter_pixels, int p_max_filter_pixels, int p_min_blob_pixels, int p_max_blob_pixels, int p_min_blobs, int p_max_blobs, int p_overload_frames, int p_extend_alarm_frames ); + void std_alarmedpixels(Image* pdiff_image, const Image* ppoly_image, unsigned int* pixel_count, unsigned int* pixel_sum); + public: - Zone( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_type, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold=15, int p_max_pixel_threshold=0, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0, int p_overload_frames=0, int p_extend_alarm_frames=0 ) - { - Setup( p_monitor, p_id, p_label, p_type, p_polygon, p_alarm_rgb, p_check_method, p_min_pixel_threshold, p_max_pixel_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs, p_overload_frames, p_extend_alarm_frames ); - } - Zone( Monitor *p_monitor, int p_id, const char *p_label, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold=15, int p_max_pixel_threshold=0, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0, int p_overload_frames=0, int p_extend_alarm_frames=0) - { - Setup( p_monitor, p_id, p_label, Zone::ACTIVE, p_polygon, p_alarm_rgb, p_check_method, p_min_pixel_threshold, p_max_pixel_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs, p_overload_frames, p_extend_alarm_frames ); - } - Zone( Monitor *p_monitor, int p_id, const char *p_label, const Polygon &p_polygon ) - { - Setup( p_monitor, p_id, p_label, Zone::INACTIVE, p_polygon, RGB_BLACK, (Zone::CheckMethod)0, 0, 0, 0, 0, Coord( 0, 0 ), 0, 0, 0, 0, 0, 0, 0, 0 ); - } - Zone( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_type, const Polygon &p_polygon ) - { - Setup( p_monitor, p_id, p_label, p_type, p_polygon, RGB_BLACK, (Zone::CheckMethod)0, 0, 0, 0, 0, Coord( 0, 0 ), 0, 0, 0, 0, 0, 0, 0, 0 ); - } + Zone( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_type, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold=15, int p_max_pixel_threshold=0, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0, int p_overload_frames=0, int p_extend_alarm_frames=0 ) + { + Setup( p_monitor, p_id, p_label, p_type, p_polygon, p_alarm_rgb, p_check_method, p_min_pixel_threshold, p_max_pixel_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs, p_overload_frames, p_extend_alarm_frames ); + } + Zone( Monitor *p_monitor, int p_id, const char *p_label, const Polygon &p_polygon, const Rgb p_alarm_rgb, CheckMethod p_check_method, int p_min_pixel_threshold=15, int p_max_pixel_threshold=0, int p_min_alarm_pixels=50, int p_max_alarm_pixels=75000, const Coord &p_filter_box=Coord( 3, 3 ), int p_min_filter_pixels=50, int p_max_filter_pixels=50000, int p_min_blob_pixels=10, int p_max_blob_pixels=0, int p_min_blobs=0, int p_max_blobs=0, int p_overload_frames=0, int p_extend_alarm_frames=0) + { + Setup( p_monitor, p_id, p_label, Zone::ACTIVE, p_polygon, p_alarm_rgb, p_check_method, p_min_pixel_threshold, p_max_pixel_threshold, p_min_alarm_pixels, p_max_alarm_pixels, p_filter_box, p_min_filter_pixels, p_max_filter_pixels, p_min_blob_pixels, p_max_blob_pixels, p_min_blobs, p_max_blobs, p_overload_frames, p_extend_alarm_frames ); + } + Zone( Monitor *p_monitor, int p_id, const char *p_label, const Polygon &p_polygon ) + { + Setup( p_monitor, p_id, p_label, Zone::INACTIVE, p_polygon, RGB_BLACK, (Zone::CheckMethod)0, 0, 0, 0, 0, Coord( 0, 0 ), 0, 0, 0, 0, 0, 0, 0, 0 ); + } + Zone( Monitor *p_monitor, int p_id, const char *p_label, ZoneType p_type, const Polygon &p_polygon ) + { + Setup( p_monitor, p_id, p_label, p_type, p_polygon, RGB_BLACK, (Zone::CheckMethod)0, 0, 0, 0, 0, Coord( 0, 0 ), 0, 0, 0, 0, 0, 0, 0, 0 ); + } public: - ~Zone(); + ~Zone(); - inline int Id() const { return( id ); } - inline const char *Label() const { return( label ); } - inline ZoneType Type() const { return( type ); } - inline bool IsActive() const { return( type == ACTIVE ); } - inline bool IsInclusive() const { return( type == INCLUSIVE ); } - inline bool IsExclusive() const { return( type == EXCLUSIVE ); } - inline bool IsPreclusive() const { return( type == PRECLUSIVE ); } - inline bool IsInactive() const { return( type == INACTIVE ); } - inline bool IsPrivacy() const { return( type == PRIVACY ); } - inline const Image *AlarmImage() const { return( image ); } - inline const Polygon &GetPolygon() const { return( polygon ); } - inline bool Alarmed() const { return( alarmed ); } - inline void SetAlarm() { alarmed = true; } - inline void ClearAlarm() { alarmed = false; } - inline Coord GetAlarmCentre() const { return( alarm_centre ); } - inline unsigned int Score() const { return( score ); } + inline int Id() const { return( id ); } + inline const char *Label() const { return( label ); } + inline ZoneType Type() const { return( type ); } + inline bool IsActive() const { return( type == ACTIVE ); } + inline bool IsInclusive() const { return( type == INCLUSIVE ); } + inline bool IsExclusive() const { return( type == EXCLUSIVE ); } + inline bool IsPreclusive() const { return( type == PRECLUSIVE ); } + inline bool IsInactive() const { return( type == INACTIVE ); } + inline bool IsPrivacy() const { return( type == PRIVACY ); } + inline const Image *AlarmImage() const { return( image ); } + inline const Polygon &GetPolygon() const { return( polygon ); } + inline bool Alarmed() const { return( alarmed ); } + inline void SetAlarm() { alarmed = true; } + inline void ClearAlarm() { alarmed = false; } + inline Coord GetAlarmCentre() const { return( alarm_centre ); } + inline unsigned int Score() const { return( score ); } - inline void ResetStats() - { - alarmed = false; - pixel_diff = 0; - alarm_pixels = 0; - alarm_filter_pixels = 0; - alarm_blob_pixels = 0; - alarm_blobs = 0; - min_blob_size = 0; - max_blob_size = 0; - score = 0; - } - void RecordStats( const Event *event ); - bool CheckAlarms( const Image *delta_image ); - bool DumpSettings( char *output, bool verbose ); + inline void ResetStats() + { + alarmed = false; + pixel_diff = 0; + alarm_pixels = 0; + alarm_filter_pixels = 0; + alarm_blob_pixels = 0; + alarm_blobs = 0; + min_blob_size = 0; + max_blob_size = 0; + score = 0; + } + void RecordStats( const Event *event ); + bool CheckAlarms( const Image *delta_image ); + bool DumpSettings( char *output, bool verbose ); - static bool ParsePolygonString( const char *polygon_string, Polygon &polygon ); - static bool ParseZoneString( const char *zone_string, int &zone_id, int &colour, Polygon &polygon ); - static int Load( Monitor *monitor, Zone **&zones ); - //================================================= - bool CheckOverloadCount(); - int GetOverloadCount(); - void SetOverloadCount(int nOverCount); - int GetOverloadFrames(); - //================================================= - bool CheckExtendAlarmCount(); - int GetExtendAlarmCount(); - void SetExtendAlarmCount(int nOverCount); - int GetExtendAlarmFrames(); - void SetScore(unsigned int nScore); - void SetAlarmImage(const Image* srcImage); + static bool ParsePolygonString( const char *polygon_string, Polygon &polygon ); + static bool ParseZoneString( const char *zone_string, int &zone_id, int &colour, Polygon &polygon ); + static int Load( Monitor *monitor, Zone **&zones ); + //================================================= + bool CheckOverloadCount(); + int GetOverloadCount(); + void SetOverloadCount(int nOverCount); + int GetOverloadFrames(); + //================================================= + bool CheckExtendAlarmCount(); + int GetExtendAlarmCount(); + void SetExtendAlarmCount(int nOverCount); + int GetExtendAlarmFrames(); + void SetScore(unsigned int nScore); + void SetAlarmImage(const Image* srcImage); - inline const Image *getPgImage() const { return( pg_image ); } - inline const Range *getRanges() const { return( ranges ); } + inline const Image *getPgImage() const { return( pg_image ); } + inline const Range *getRanges() const { return( ranges ); } }; diff --git a/src/zma.cpp b/src/zma.cpp index 2d22d713a..03ffe1726 100644 --- a/src/zma.cpp +++ b/src/zma.cpp @@ -41,9 +41,9 @@ behind. =head1 OPTIONS - -m, --monitor_id - ID of the monitor to analyse - -h, --help - Display usage information - -v, --version - Print the installed version of ZoneMinder + -m, --monitor_id - ID of the monitor to analyse + -h, --help - Display usage information + -v, --version - Print the installed version of ZoneMinder =cut @@ -59,146 +59,146 @@ behind. void Usage() { - fprintf( stderr, "zma -m \n" ); - fprintf( stderr, "Options:\n" ); - fprintf( stderr, " -m, --monitor : Specify which monitor to use\n" ); - fprintf( stderr, " -h, --help : This screen\n" ); - fprintf( stderr, " -v, --version : Report the installed version of ZoneMinder\n" ); - exit( 0 ); + fprintf( stderr, "zma -m \n" ); + fprintf( stderr, "Options:\n" ); + fprintf( stderr, " -m, --monitor : Specify which monitor to use\n" ); + fprintf( stderr, " -h, --help : This screen\n" ); + fprintf( stderr, " -v, --version : Report the installed version of ZoneMinder\n" ); + exit( 0 ); } int main( int argc, char *argv[] ) { - self = argv[0]; + self = argv[0]; - srand( getpid() * time( 0 ) ); + srand( getpid() * time( 0 ) ); - int id = -1; + int id = -1; - static struct option long_options[] = { - {"monitor", 1, 0, 'm'}, - {"help", 0, 0, 'h'}, - {"version", 0, 0, 'v'}, - {0, 0, 0, 0} - }; + static struct option long_options[] = { + {"monitor", 1, 0, 'm'}, + {"help", 0, 0, 'h'}, + {"version", 0, 0, 'v'}, + {0, 0, 0, 0} + }; - while (1) - { - int option_index = 0; + while (1) + { + int option_index = 0; - int c = getopt_long (argc, argv, "m:h:v", long_options, &option_index); - if (c == -1) - { - break; - } + int c = getopt_long (argc, argv, "m:h:v", long_options, &option_index); + if (c == -1) + { + break; + } - switch (c) - { - case 'm': - id = atoi(optarg); - break; - case 'h': - case '?': - Usage(); - break; - case 'v': - std::cout << ZM_VERSION << "\n"; - exit(0); - default: - //fprintf( stderr, "?? getopt returned character code 0%o ??\n", c ); - break; - } - } + switch (c) + { + case 'm': + id = atoi(optarg); + break; + case 'h': + case '?': + Usage(); + break; + case 'v': + std::cout << ZM_VERSION << "\n"; + exit(0); + default: + //fprintf( stderr, "?? getopt returned character code 0%o ??\n", c ); + break; + } + } - if (optind < argc) - { - fprintf( stderr, "Extraneous options, " ); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - Usage(); - } + if (optind < argc) + { + fprintf( stderr, "Extraneous options, " ); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + Usage(); + } - if ( id < 0 ) - { - fprintf( stderr, "Bogus monitor %d\n", id ); - Usage(); - exit( 0 ); - } + if ( id < 0 ) + { + fprintf( stderr, "Bogus monitor %d\n", id ); + Usage(); + exit( 0 ); + } - char log_id_string[16]; - snprintf( log_id_string, sizeof(log_id_string), "zma_m%d", id ); + char log_id_string[16]; + snprintf( log_id_string, sizeof(log_id_string), "zma_m%d", id ); - zmLoadConfig(); + zmLoadConfig(); - logInit( log_id_string ); - - ssedetect(); + logInit( log_id_string ); + + ssedetect(); - Monitor *monitor = Monitor::Load( id, true, Monitor::ANALYSIS ); + Monitor *monitor = Monitor::Load( id, true, Monitor::ANALYSIS ); - if ( monitor ) - { - Info( "In mode %d/%d, warming up", monitor->GetFunction(), monitor->Enabled() ); + if ( monitor ) + { + Info( "In mode %d/%d, warming up", monitor->GetFunction(), monitor->Enabled() ); - if ( config.opt_frame_server ) - { - Event::OpenFrameSocket( monitor->Id() ); - } + if ( config.opt_frame_server ) + { + Event::OpenFrameSocket( monitor->Id() ); + } - zmSetDefaultHupHandler(); - zmSetDefaultTermHandler(); - zmSetDefaultDieHandler(); + zmSetDefaultHupHandler(); + zmSetDefaultTermHandler(); + zmSetDefaultDieHandler(); - sigset_t block_set; - sigemptyset( &block_set ); + sigset_t block_set; + sigemptyset( &block_set ); - useconds_t analysis_rate = monitor->GetAnalysisRate(); - unsigned int analysis_update_delay = monitor->GetAnalysisUpdateDelay(); - time_t last_analysis_update_time, cur_time; - monitor->UpdateAdaptiveSkip(); - last_analysis_update_time = time( 0 ); + useconds_t analysis_rate = monitor->GetAnalysisRate(); + unsigned int analysis_update_delay = monitor->GetAnalysisUpdateDelay(); + time_t last_analysis_update_time, cur_time; + monitor->UpdateAdaptiveSkip(); + last_analysis_update_time = time( 0 ); - while( !zm_terminate ) - { - // Process the next image - sigprocmask( SIG_BLOCK, &block_set, 0 ); + while( !zm_terminate ) + { + // Process the next image + sigprocmask( SIG_BLOCK, &block_set, 0 ); - // Some periodic updates are required for variable capturing framerate - if ( analysis_update_delay ) - { - cur_time = time( 0 ); - if ( ( cur_time - last_analysis_update_time ) > analysis_update_delay ) - { - analysis_rate = monitor->GetAnalysisRate(); - monitor->UpdateAdaptiveSkip(); - last_analysis_update_time = cur_time; - } - } + // Some periodic updates are required for variable capturing framerate + if ( analysis_update_delay ) + { + cur_time = time( 0 ); + if ( ( cur_time - last_analysis_update_time ) > analysis_update_delay ) + { + analysis_rate = monitor->GetAnalysisRate(); + monitor->UpdateAdaptiveSkip(); + last_analysis_update_time = cur_time; + } + } - if ( !monitor->Analyse() ) - { - usleep( monitor->Active()?ZM_SAMPLE_RATE:ZM_SUSPENDED_RATE ); - } - else if ( analysis_rate ) - { - usleep( analysis_rate ); - } + if ( !monitor->Analyse() ) + { + usleep( monitor->Active()?ZM_SAMPLE_RATE:ZM_SUSPENDED_RATE ); + } + else if ( analysis_rate ) + { + usleep( analysis_rate ); + } - if ( zm_reload ) - { - monitor->Reload(); - zm_reload = false; - } - sigprocmask( SIG_UNBLOCK, &block_set, 0 ); - } - delete monitor; - } - else - { - fprintf( stderr, "Can't find monitor with id of %d\n", id ); - } - logTerm(); - zmDbClose(); - return( 0 ); + if ( zm_reload ) + { + monitor->Reload(); + zm_reload = false; + } + sigprocmask( SIG_UNBLOCK, &block_set, 0 ); + } + delete monitor; + } + else + { + fprintf( stderr, "Can't find monitor with id of %d\n", id ); + } + logTerm(); + zmDbClose(); + return( 0 ); } diff --git a/src/zmc.cpp b/src/zmc.cpp index 56417d044..42b6b7aff 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -44,12 +44,12 @@ possible, this should run at more or less constant speed. =head1 OPTIONS - -d, --device - For local cameras, device to access. e.g /dev/video0 etc + -d, --device - For local cameras, device to access. e.g /dev/video0 etc -r -H -P -p - For remote cameras - -f, --file - For local images, jpg file to access. - -m, --monitor_id - ID of the monitor to analyse - -h, --help - Display usage information - -v, --version - Print the installed version of ZoneMinder + -f, --file - For local images, jpg file to access. + -m, --monitor_id - ID of the monitor to analyse + -h, --help - Display usage information + -v, --version - Print the installed version of ZoneMinder =cut @@ -75,290 +75,290 @@ possible, this should run at more or less constant speed. void Usage() { - fprintf( stderr, "zmc -d or -r -H -P -p or -f or -m \n" ); + fprintf( stderr, "zmc -d or -r -H -P -p or -f or -m \n" ); - fprintf( stderr, "Options:\n" ); + fprintf( stderr, "Options:\n" ); #if defined(BSD) - fprintf( stderr, " -d, --device : For local cameras, device to access. E.g /dev/bktr0 etc\n" ); + fprintf( stderr, " -d, --device : For local cameras, device to access. E.g /dev/bktr0 etc\n" ); #else - fprintf( stderr, " -d, --device : For local cameras, device to access. E.g /dev/video0 etc\n" ); + fprintf( stderr, " -d, --device : For local cameras, device to access. E.g /dev/video0 etc\n" ); #endif - fprintf( stderr, " -r -H -P -p : For remote cameras\n" ); - fprintf( stderr, " -f, --file : For local images, jpg file to access.\n" ); - fprintf( stderr, " -m, --monitor : For sources associated with a single monitor\n" ); - fprintf( stderr, " -h, --help : This screen\n" ); - fprintf( stderr, " -v, --version : Report the installed version of ZoneMinder\n" ); - exit( 0 ); + fprintf( stderr, " -r -H -P -p : For remote cameras\n" ); + fprintf( stderr, " -f, --file : For local images, jpg file to access.\n" ); + fprintf( stderr, " -m, --monitor : For sources associated with a single monitor\n" ); + fprintf( stderr, " -h, --help : This screen\n" ); + fprintf( stderr, " -v, --version : Report the installed version of ZoneMinder\n" ); + exit( 0 ); } int main( int argc, char *argv[] ) { - self = argv[0]; + self = argv[0]; - srand( getpid() * time( 0 ) ); + srand( getpid() * time( 0 ) ); - const char *device = ""; - const char *protocol = ""; - const char *host = ""; - const char *port = ""; - const char *path = ""; - const char *file = ""; - int monitor_id = -1; + const char *device = ""; + const char *protocol = ""; + const char *host = ""; + const char *port = ""; + const char *path = ""; + const char *file = ""; + int monitor_id = -1; - static struct option long_options[] = { - {"device", 1, 0, 'd'}, - {"protocol", 1, 0, 'r'}, - {"host", 1, 0, 'H'}, - {"port", 1, 0, 'P'}, - {"path", 1, 0, 'p'}, - {"file", 1, 0, 'f'}, - {"monitor", 1, 0, 'm'}, - {"help", 0, 0, 'h'}, - {"version", 0, 0, 'v'}, - {0, 0, 0, 0} - }; + static struct option long_options[] = { + {"device", 1, 0, 'd'}, + {"protocol", 1, 0, 'r'}, + {"host", 1, 0, 'H'}, + {"port", 1, 0, 'P'}, + {"path", 1, 0, 'p'}, + {"file", 1, 0, 'f'}, + {"monitor", 1, 0, 'm'}, + {"help", 0, 0, 'h'}, + {"version", 0, 0, 'v'}, + {0, 0, 0, 0} + }; - while (1) - { - int option_index = 0; + while (1) + { + int option_index = 0; - int c = getopt_long (argc, argv, "d:H:P:p:f:m:h:v", long_options, &option_index); - if (c == -1) - { - break; - } + int c = getopt_long (argc, argv, "d:H:P:p:f:m:h:v", long_options, &option_index); + if (c == -1) + { + break; + } - switch (c) - { - case 'd': - device = optarg; - break; - case 'H': - host = optarg; - break; - case 'P': - port = optarg; - break; - case 'p': - path = optarg; - break; - case 'f': - file = optarg; - break; - case 'm': - monitor_id = atoi(optarg); - break; - case 'h': - case '?': - Usage(); - break; - case 'v': - std::cout << ZM_VERSION << "\n"; - exit(0); - default: - //fprintf( stderr, "?? getopt returned character code 0%o ??\n", c ); - break; - } - } + switch (c) + { + case 'd': + device = optarg; + break; + case 'H': + host = optarg; + break; + case 'P': + port = optarg; + break; + case 'p': + path = optarg; + break; + case 'f': + file = optarg; + break; + case 'm': + monitor_id = atoi(optarg); + break; + case 'h': + case '?': + Usage(); + break; + case 'v': + std::cout << ZM_VERSION << "\n"; + exit(0); + default: + //fprintf( stderr, "?? getopt returned character code 0%o ??\n", c ); + break; + } + } - if (optind < argc) - { - fprintf( stderr, "Extraneous options, " ); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - Usage(); - } + if (optind < argc) + { + fprintf( stderr, "Extraneous options, " ); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + Usage(); + } - int modes = ( device[0]?1:0 + host[0]?1:0 + file[0]?1:0 + (monitor_id>0?1:0) ); - if ( modes > 1 ) - { - fprintf( stderr, "Only one of device, host/port/path, file or monitor id allowed\n" ); - Usage(); - exit( 0 ); - } + int modes = ( device[0]?1:0 + host[0]?1:0 + file[0]?1:0 + (monitor_id>0?1:0) ); + if ( modes > 1 ) + { + fprintf( stderr, "Only one of device, host/port/path, file or monitor id allowed\n" ); + Usage(); + exit( 0 ); + } - if ( modes < 1 ) - { - fprintf( stderr, "One of device, host/port/path, file or monitor id must be specified\n" ); - Usage(); - exit( 0 ); - } + if ( modes < 1 ) + { + fprintf( stderr, "One of device, host/port/path, file or monitor id must be specified\n" ); + Usage(); + exit( 0 ); + } - char log_id_string[32] = ""; - if ( device[0] ) - { - const char *slash_ptr = strrchr( device, '/' ); - snprintf( log_id_string, sizeof(log_id_string), "zmc_d%s", slash_ptr?slash_ptr+1:device ); - } - else if ( host[0] ) - { - snprintf( log_id_string, sizeof(log_id_string), "zmc_h%s", host ); - } - else if ( file[0] ) - { - const char *slash_ptr = strrchr( file, '/' ); - snprintf( log_id_string, sizeof(log_id_string), "zmc_f%s", slash_ptr?slash_ptr+1:file ); - } - else - { - snprintf( log_id_string, sizeof(log_id_string), "zmc_m%d", monitor_id ); - } + char log_id_string[32] = ""; + if ( device[0] ) + { + const char *slash_ptr = strrchr( device, '/' ); + snprintf( log_id_string, sizeof(log_id_string), "zmc_d%s", slash_ptr?slash_ptr+1:device ); + } + else if ( host[0] ) + { + snprintf( log_id_string, sizeof(log_id_string), "zmc_h%s", host ); + } + else if ( file[0] ) + { + const char *slash_ptr = strrchr( file, '/' ); + snprintf( log_id_string, sizeof(log_id_string), "zmc_f%s", slash_ptr?slash_ptr+1:file ); + } + else + { + snprintf( log_id_string, sizeof(log_id_string), "zmc_m%d", monitor_id ); + } - zmLoadConfig(); + zmLoadConfig(); - logInit( log_id_string ); - - ssedetect(); + logInit( log_id_string ); + + ssedetect(); - Monitor **monitors = 0; - int n_monitors = 0; + Monitor **monitors = 0; + int n_monitors = 0; #if ZM_HAS_V4L - if ( device[0] ) - { - n_monitors = Monitor::LoadLocalMonitors( device, monitors, Monitor::CAPTURE ); - } - else + if ( device[0] ) + { + n_monitors = Monitor::LoadLocalMonitors( device, monitors, Monitor::CAPTURE ); + } + else #endif // ZM_HAS_V4L - if ( host[0] ) - { - if ( !port ) - port = "80"; - n_monitors = Monitor::LoadRemoteMonitors( protocol, host, port, path, monitors, Monitor::CAPTURE ); - } - else if ( file[0] ) - { - n_monitors = Monitor::LoadFileMonitors( file, monitors, Monitor::CAPTURE ); - } - else - { - Monitor *monitor = Monitor::Load( monitor_id, true, Monitor::CAPTURE ); - if ( monitor ) - { - monitors = new Monitor *[1]; - monitors[0] = monitor; - n_monitors = 1; - } - } + if ( host[0] ) + { + if ( !port ) + port = "80"; + n_monitors = Monitor::LoadRemoteMonitors( protocol, host, port, path, monitors, Monitor::CAPTURE ); + } + else if ( file[0] ) + { + n_monitors = Monitor::LoadFileMonitors( file, monitors, Monitor::CAPTURE ); + } + else + { + Monitor *monitor = Monitor::Load( monitor_id, true, Monitor::CAPTURE ); + if ( monitor ) + { + monitors = new Monitor *[1]; + monitors[0] = monitor; + n_monitors = 1; + } + } - if ( !n_monitors ) - { - Error( "No monitors found" ); - exit ( -1 ); - } + if ( !n_monitors ) + { + Error( "No monitors found" ); + exit ( -1 ); + } - Info( "Starting Capture version %s", ZM_VERSION ); + Info( "Starting Capture version %s", ZM_VERSION ); - zmSetDefaultTermHandler(); - zmSetDefaultDieHandler(); + zmSetDefaultTermHandler(); + zmSetDefaultDieHandler(); - sigset_t block_set; - sigemptyset( &block_set ); + sigset_t block_set; + sigemptyset( &block_set ); - sigaddset( &block_set, SIGUSR1 ); - sigaddset( &block_set, SIGUSR2 ); + sigaddset( &block_set, SIGUSR1 ); + sigaddset( &block_set, SIGUSR2 ); - if ( monitors[0]->PrimeCapture() < 0 ) - { - Error( "Failed to prime capture of initial monitor" ); - exit( -1 ); - } + if ( monitors[0]->PrimeCapture() < 0 ) + { + Error( "Failed to prime capture of initial monitor" ); + exit( -1 ); + } - long *capture_delays = new long[n_monitors]; - long *alarm_capture_delays = new long[n_monitors]; - long *next_delays = new long[n_monitors]; - struct timeval * last_capture_times = new struct timeval[n_monitors]; - for ( int i = 0; i < n_monitors; i++ ) - { - last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0; - capture_delays[i] = monitors[i]->GetCaptureDelay(); - alarm_capture_delays[i] = monitors[i]->GetAlarmCaptureDelay(); - } + long *capture_delays = new long[n_monitors]; + long *alarm_capture_delays = new long[n_monitors]; + long *next_delays = new long[n_monitors]; + struct timeval * last_capture_times = new struct timeval[n_monitors]; + for ( int i = 0; i < n_monitors; i++ ) + { + last_capture_times[i].tv_sec = last_capture_times[i].tv_usec = 0; + capture_delays[i] = monitors[i]->GetCaptureDelay(); + alarm_capture_delays[i] = monitors[i]->GetAlarmCaptureDelay(); + } - int result = 0; - struct timeval now; - struct DeltaTimeval delta_time; - while( !zm_terminate ) - { - sigprocmask( SIG_BLOCK, &block_set, 0 ); - for ( int i = 0; i < n_monitors; i++ ) - { - long min_delay = MAXINT; + int result = 0; + struct timeval now; + struct DeltaTimeval delta_time; + while( !zm_terminate ) + { + sigprocmask( SIG_BLOCK, &block_set, 0 ); + for ( int i = 0; i < n_monitors; i++ ) + { + long min_delay = MAXINT; - gettimeofday( &now, NULL ); - for ( int j = 0; j < n_monitors; j++ ) - { - if ( last_capture_times[j].tv_sec ) - { - DELTA_TIMEVAL( delta_time, now, last_capture_times[j], DT_PREC_3 ); - if ( monitors[i]->GetState() == Monitor::ALARM ) - next_delays[j] = alarm_capture_delays[j]-delta_time.delta; - else - next_delays[j] = capture_delays[j]-delta_time.delta; - if ( next_delays[j] < 0 ) - next_delays[j] = 0; - } - else - { - next_delays[j] = 0; - } - if ( next_delays[j] <= min_delay ) - { - min_delay = next_delays[j]; - } - } + gettimeofday( &now, NULL ); + for ( int j = 0; j < n_monitors; j++ ) + { + if ( last_capture_times[j].tv_sec ) + { + DELTA_TIMEVAL( delta_time, now, last_capture_times[j], DT_PREC_3 ); + if ( monitors[i]->GetState() == Monitor::ALARM ) + next_delays[j] = alarm_capture_delays[j]-delta_time.delta; + else + next_delays[j] = capture_delays[j]-delta_time.delta; + if ( next_delays[j] < 0 ) + next_delays[j] = 0; + } + else + { + next_delays[j] = 0; + } + if ( next_delays[j] <= min_delay ) + { + min_delay = next_delays[j]; + } + } - if ( next_delays[i] <= min_delay || next_delays[i] <= 0 ) - { - if ( monitors[i]->PreCapture() < 0 ) - { - Error( "Failed to pre-capture monitor %d %d (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors ); - zm_terminate = true; - result = -1; - break; - } - if ( monitors[i]->Capture() < 0 ) - { - Error( "Failed to capture image from monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors ); - zm_terminate = true; - result = -1; - break; - } - if ( monitors[i]->PostCapture() < 0 ) - { - Error( "Failed to post-capture monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors ); - zm_terminate = true; - result = -1; - break; - } + if ( next_delays[i] <= min_delay || next_delays[i] <= 0 ) + { + if ( monitors[i]->PreCapture() < 0 ) + { + Error( "Failed to pre-capture monitor %d %d (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors ); + zm_terminate = true; + result = -1; + break; + } + if ( monitors[i]->Capture() < 0 ) + { + Error( "Failed to capture image from monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors ); + zm_terminate = true; + result = -1; + break; + } + if ( monitors[i]->PostCapture() < 0 ) + { + Error( "Failed to post-capture monitor %d %s (%d/%d)", monitors[i]->Id(), monitors[i]->Name(), i+1, n_monitors ); + zm_terminate = true; + result = -1; + break; + } - if ( next_delays[i] > 0 ) - { - gettimeofday( &now, NULL ); - DELTA_TIMEVAL( delta_time, now, last_capture_times[i], DT_PREC_3 ); - long sleep_time = next_delays[i]-delta_time.delta; - if ( sleep_time > 0 ) - { - usleep( sleep_time*(DT_MAXGRAN/DT_PREC_3) ); - } - } - gettimeofday( &(last_capture_times[i]), NULL ); - } - } - sigprocmask( SIG_UNBLOCK, &block_set, 0 ); - } - for ( int i = 0; i < n_monitors; i++ ) - { - delete monitors[i]; - } - delete [] monitors; - delete [] alarm_capture_delays; - delete [] capture_delays; - delete [] next_delays; - delete [] last_capture_times; + if ( next_delays[i] > 0 ) + { + gettimeofday( &now, NULL ); + DELTA_TIMEVAL( delta_time, now, last_capture_times[i], DT_PREC_3 ); + long sleep_time = next_delays[i]-delta_time.delta; + if ( sleep_time > 0 ) + { + usleep( sleep_time*(DT_MAXGRAN/DT_PREC_3) ); + } + } + gettimeofday( &(last_capture_times[i]), NULL ); + } + } + sigprocmask( SIG_UNBLOCK, &block_set, 0 ); + } + for ( int i = 0; i < n_monitors; i++ ) + { + delete monitors[i]; + } + delete [] monitors; + delete [] alarm_capture_delays; + delete [] capture_delays; + delete [] next_delays; + delete [] last_capture_times; - logTerm(); - zmDbClose(); + logTerm(); + zmDbClose(); - return( result ); + return( result ); } diff --git a/src/zmf.h b/src/zmf.h index f00ffa891..211577309 100644 --- a/src/zmf.h +++ b/src/zmf.h @@ -22,11 +22,11 @@ struct FrameHeader { - unsigned long event_id; - time_t event_time; - unsigned long frame_id; - bool alarm_frame; - unsigned long image_length; + unsigned long event_id; + time_t event_time; + unsigned long frame_id; + bool alarm_frame; + unsigned long image_length; }; #endif // ZMFILE_H diff --git a/src/zms.cpp b/src/zms.cpp index 9e190e447..ca38926ac 100644 --- a/src/zms.cpp +++ b/src/zms.cpp @@ -62,7 +62,7 @@ int main( int argc, const char *argv[] ) int monitor_id = 0; time_t event_time = 0; int event_id = 0; - int frame_id = 1; + unsigned int frame_id = 1; unsigned int scale = 100; unsigned int rate = 100; double maxfps = 10.0; diff --git a/src/zmstreamer.cpp b/src/zmstreamer.cpp new file mode 100644 index 000000000..b33c61246 --- /dev/null +++ b/src/zmstreamer.cpp @@ -0,0 +1,252 @@ +// +// ZoneMinder Streamer, $Date: 2010-10-14 23:21:00 +0200 (Thu, 14 Oct 2010) $ +// Copyright (C) 2001-2010 Philip Coombes, Chris Kistner +// +// This program is based on revision 3143 of +// http://svn.zoneminder.com/svn/zm/trunk/src/zms.cpp +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/* + +=head1 NAME + +zmstreamer - eyeZM video streamer + +=head1 SYNOPSIS + + zmstreamer -e + zmstreamer -o + zmstreamer -u + zmstreamer -f + zmstreamer -s + zmstreamer -b + zmstreamer -m + zmstreamer -d + zmstreamer -i + zmstreamer -? + zmstreamer -h + zmstreamer -v + +=head1 DESCRIPTION + +*DEPRECIATED* The xml skin and all files associated with the xml skin are now +depreciated. Please use the ZoneMinder API instead. + +This binary works in conjunction with the XML skin to stream video to iPhones +running the eyeZm app. + +=head1 OPTIONS + + -e - Specify output mode: mpeg/jpg/zip/single/raw. + -o - Specify output format. + -u - Specify buffer size in ms. + -f - Specify maximum framerate. + -s - Specify scale. + -b - Specify bitrate. + -m - Specify monitor id. + -d - 0 = off, 1 = no streaming, 2 = with streaming. + -i, -?, -h - Display usage information + -v - Print the installed version of ZoneMinder + +=cut + +*/ + +#include +#include + +#include +#include + +#include "zm.h" +#include "zm_db.h" +#include "zm_user.h" +#include "zm_signal.h" +#include "zm_monitor.h" +#include "zm_stream.h" + +// Possible command-line options +#define OPTIONS "e:o:u:f:s:b:m:d:i:?:h:v" + +// Default ZMS values +#define ZMS_DEFAULT_DEBUG 0 +#define ZMS_DEFAULT_ID 1 +#define ZMS_DEFAULT_BITRATE 100000 +#define ZMS_DEFAULT_SCALE 100 +#define ZMS_DEFAULT_MODE "mpeg" +#define ZMS_DEFAULT_FORMAT "asf" +#define ZMS_DEFAULT_FPS 25.0 +#define ZMS_DEFAULT_BUFFER 1000 + +int main(int argc, char** argv) { + self = argv[0]; + // Set initial values to the default values + int debug = ZMS_DEFAULT_DEBUG; + int id = ZMS_DEFAULT_ID; + int bitrate = ZMS_DEFAULT_BITRATE; + int scale = ZMS_DEFAULT_SCALE; + char mode[32]; + sprintf(mode, "%s", ZMS_DEFAULT_MODE); + char format[32]; + sprintf(format, "%s", ZMS_DEFAULT_FORMAT); + double maxfps = ZMS_DEFAULT_FPS; + int buffer = ZMS_DEFAULT_BUFFER; + + // Parse command-line options + int arg; + while ((arg = getopt(argc, argv, OPTIONS)) != -1) { + switch (arg) { + case 'e': + sprintf(mode, "%s", optarg); + break; + case 'o': + sprintf(format, "%s", optarg); + break; + case 'u': + buffer = atoi(optarg); + break; + case 'f': + maxfps = atof(optarg); + break; + case 's': + scale = atoi(optarg); + break; + case 'b': + bitrate = atoi(optarg); + break; + case 'm': + id = atoi(optarg); + break; + case 'd': + debug = atoi(optarg); + break; + case 'h': + case 'i': + case '?': + printf("-e : Specify output mode: mpeg/jpg/zip/single/raw. Default = %s\n", ZMS_DEFAULT_MODE); + printf("-o : Specify output format. Default = %s\n", ZMS_DEFAULT_FORMAT); + printf("-u : Specify buffer size in ms. Default = %d\n", ZMS_DEFAULT_BUFFER); + printf("-f : Specify maximum framerate. Default = %lf\n", ZMS_DEFAULT_FPS); + printf("-s : Specify scale. Default = %d\n", ZMS_DEFAULT_SCALE); + printf("-b : Specify bitrate. Default = %d\n", ZMS_DEFAULT_BITRATE); + printf("-m : Specify monitor id. Default = %d\n", ZMS_DEFAULT_ID); + printf("-d : 0 = off, 1 = no streaming, 2 = with streaming. Default = 0\n"); + printf("-i or -? or -h: This information\n"); + printf("-v : This installed version of ZoneMinder\n"); + return EXIT_SUCCESS; + case 'v': + std::cout << ZM_VERSION << "\n"; + exit(0); + } + } + + // Set stream type + StreamBase::StreamType streamtype; + if (!strcasecmp("raw", mode)) + streamtype = MonitorStream::STREAM_RAW; + else if (!strcasecmp("mpeg", mode)) + streamtype = MonitorStream::STREAM_MPEG; + else if (!strcasecmp("jpg", mode)) + streamtype = MonitorStream::STREAM_JPEG; + else if (!strcasecmp("single", mode)) + streamtype = MonitorStream::STREAM_SINGLE; + else if (!strcasecmp("zip", mode)) + streamtype = MonitorStream::STREAM_ZIP; + else + streamtype = MonitorStream::STREAM_MPEG; + + if (debug) { + // Show stream parameters + printf("Stream parameters:\n"); + switch (streamtype) { + case MonitorStream::STREAM_MPEG: + printf("Output mode (-e) = %s\n", "mpeg"); + printf("Output format (-o) = %s\n", format); + break; + default: + printf("Output mode (-e) = %s\n", mode); + } + printf("Buffer size (-u) = %d ms\n", buffer); + printf("Maximum FPS (-f) = %lf FPS\n", maxfps); + printf("Scale (-s) = %d%%\n", scale); + printf("Bitrate (-b) = %d bps\n", bitrate); + printf("Monitor Id (-m) = %d\n", id); + } + + if (debug) { + // Set ZM debugger to print to stdout + printf("Setting up ZoneMinder debugger to print to stdout..."); + setenv("ZM_DBG_PRINT", "1", 1); + printf("Done.\n"); + } + + // Loading ZM configurations + printf("Loading ZoneMinder configurations..."); + zmLoadConfig(); + printf("Done.\n"); + + logInit("zmstreamer"); + + ssedetect(); + + // Setting stream parameters + MonitorStream stream; + stream.setStreamScale(scale); // default = 100 (scale) + stream.setStreamReplayRate(100); // default = 100 (rate) + stream.setStreamMaxFPS(maxfps); // default = 10 (maxfps) + if (debug) stream.setStreamTTL(1); + else stream.setStreamTTL(0); // default = 0 (ttl) + stream.setStreamQueue(0); // default = 0 (connkey) + stream.setStreamBuffer(buffer); // default = 0 (buffer) + stream.setStreamStart(id); // default = 0 (monitor_id) + stream.setStreamType(streamtype); + if (streamtype == MonitorStream::STREAM_MPEG) { +#if HAVE_LIBAVCODEC + if (debug) printf("HAVE_LIBAVCODEC is set\n"); + stream.setStreamFormat(format); // default = "" (format) + stream.setStreamBitrate(bitrate); // default = 100000 (bitrate) +#else + fprintf(stderr, "MPEG streaming is disabled.\nYou should configure with the --with-ffmpeg option and rebuild to use this functionality.\n"); + logTerm(); + zmDbClose(); + return EXIT_FAILURE; +#endif + } + + if (debug != 1) { + if (debug) printf("Running stream..."); + + // Output headers + fprintf(stdout, "Server: ZoneMinder Video Server/%s\r\n", ZM_VERSION); + time_t now = time(0); + char date_string[64]; + strftime(date_string, sizeof (date_string) - 1, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now)); + fprintf(stdout, "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n"); + fprintf(stdout, "Last-Modified: %s\r\n", date_string); + fprintf(stdout, "Cache-Control: no-store, no-cache, must-revalidate\r\n"); + fprintf(stdout, "Cache-Control: post-check=0, pre-check=0\r\n"); + fprintf(stdout, "Pragma: no-cache\r\n"); + + // Run stream + stream.runStream(); + } + if (debug) printf("Done.\n"); + + logTerm(); + zmDbClose(); + + return (EXIT_SUCCESS); +} diff --git a/src/zmu.cpp b/src/zmu.cpp index 188362446..21cbe19aa 100644 --- a/src/zmu.cpp +++ b/src/zmu.cpp @@ -756,15 +756,14 @@ int main( int argc, char *argv[] ) if ( function & ZMU_LIST ) { - char sql[ZM_SQL_SML_BUFSIZ]; - strncpy( sql, "select Id, Function+0 from Monitors", sizeof(sql) ); + std::string sql = "select Id, Function+0 from Monitors"; if ( !verbose ) { - strncat( sql, " where Function != 'None'", sizeof(sql)-strlen(sql) ); + sql += "where Function != 'None'"; } - strncat( sql, " order by Id asc", sizeof(sql)-strlen(sql) ); + sql += " order by Id asc"; - if ( mysql_query( &dbconn, sql ) ) + if ( mysql_query( &dbconn, sql.c_str() ) ) { Error( "Can't run query: %s", mysql_error( &dbconn ) ); exit( mysql_errno( &dbconn ) ); diff --git a/web/includes/Frame.php b/web/includes/Frame.php new file mode 100644 index 000000000..b7add3b0e --- /dev/null +++ b/web/includes/Frame.php @@ -0,0 +1,76 @@ + $v) { + $this->{$k} = $v; + } + } else { + Error("No row for Frame " . $IdOrRow ); + } + } // end function __construct + public function Storage() { + return $this->Event()->Storage(); + } + public function Event() { + return new Event( $this->{'EventId'} ); + } + public function __call( $fn, array $args){ + if(isset($this->{$fn})){ + return $this->{$fn}; +#array_unshift($args, $this); +#call_user_func_array( $this->{$fn}, $args); + } + } + + public function Path() { + $Storage = $this->Storage(); + return $Storage->Path().'/'.$this->Relative_Path(); + } + public function Relative_Path() { + $event_path = ""; + + if ( ZM_USE_DEEP_STORAGE ) + { + $event_path = + $this->{'MonitorId'} + .'/'.strftime( "%y/%m/%d/%H/%M/%S", + $this->Time() + ) + ; + } + else + { + $event_path = + $this->{'MonitorId'} + .'/'.$this->{'Id'} + ; + } + + return( $event_path ); + + } + + public function getImageSrc( ) { + return ZM_BASE_URL.'/index.php?view=image&fid='.$this->{'Id'}; + } // end function getImageSrc +} # end class +?> diff --git a/web/includes/actions.php b/web/includes/actions.php index 1ceda8231..74689c95c 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -527,6 +527,7 @@ if ( !empty($action) ) 'DoNativeMotDet' => 'toggle', 'Exif' => 'toggle', 'RTSPDescribe' => 'toggle', + 'RecordAudio' => 'toggle', ); $columns = getTableColumns( 'Monitors' ); diff --git a/web/includes/config.php.in b/web/includes/config.php.in index 2ca819210..ba96d9a54 100644 --- a/web/includes/config.php.in +++ b/web/includes/config.php.in @@ -104,6 +104,7 @@ define( "CMD_PREV", 12 ); define( "CMD_NEXT", 13 ); define( "CMD_SEEK", 14 ); define( "CMD_VARPLAY", 15 ); +define( "CMD_QUIT", 17 ); define( "CMD_QUERY", 99 ); // diff --git a/web/includes/functions.php b/web/includes/functions.php index 36e8dc8ce..abf6246b3 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -217,14 +217,20 @@ function getMimeType( $file ) return( trim( exec( 'file -bi '.escapeshellarg( $file ).' 2>/dev/null' ) ) ); } -function outputVideoStream( $id, $src, $width, $height, $format, $title="" ) -{ - if ( file_exists( $src ) ) +function outputVideoStream( $id, $src, $width, $height, $format, $title="" ) { + echo getVideoStreamHTML( $id, $src, $width, $height, $format, $title ); +} + +function getVideoStreamHTML( $id, $src, $width, $height, $format, $title="" ) { + $html = ''; + $width = validInt($width); + $height = validInt($height); + $title = validHtmlStr($title); + + if ( file_exists( $src ) ) { $mimeType = getMimeType( $src ); - else - { - switch( $format ) - { + } else { + switch( $format ) { case 'asf' : $mimeType = "video/x-ms-asf"; break; @@ -252,118 +258,95 @@ function outputVideoStream( $id, $src, $width, $height, $format, $title="" ) } if ( !$mimeType || ($mimeType == 'application/octet-stream') ) $mimeType = 'video/'.$format; - $objectTag = false; - if ( ZM_WEB_USE_OBJECT_TAGS ) - { - switch( $mimeType ) - { + if ( ZM_WEB_USE_OBJECT_TAGS ) { + switch( $mimeType ) { case "video/x-ms-asf" : case "video/x-msvideo" : case "video/mp4" : { - if ( isWindows() ) - { - ?> - - + type="'.$mimeType.'"> + - - - '; } - break; } case "video/quicktime" : { - ?> - - + type="'.$mimeType.'"> + - - - '; } case "application/x-shockwave-flash" : { - ?> - - + type="'.$mimeType.'"> + - - - '; } - } - } - if ( !$objectTag ) - { - ?> - - src="" - name="" - width="" - height="" + } # end switch + } # end if use object tags + return ' - - '; } -function outputImageStream( $id, $src, $width, $height, $title="" ) -{ +function outputImageStream( $id, $src, $width, $height, $title="" ) { + echo getImageStream( $id, $src, $width, $height, $title ); +} + + +function getImageStream( $id, $src, $width, $height, $title="" ) { if ( canStreamIframe() ) { - ?> -